Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/os.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | 9f12ede5571a |
children | f08d439fab8c |
rev | line source |
---|---|
0 | 1 /* |
2250 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/javaClasses.hpp" | |
28 #include "classfile/systemDictionary.hpp" | |
29 #include "classfile/vmSymbols.hpp" | |
30 #include "code/icBuffer.hpp" | |
31 #include "code/vtableStubs.hpp" | |
32 #include "gc_implementation/shared/vmGCOperations.hpp" | |
33 #include "interpreter/interpreter.hpp" | |
34 #include "memory/allocation.inline.hpp" | |
35 #include "oops/oop.inline.hpp" | |
36 #include "prims/jvm.h" | |
37 #include "prims/jvm_misc.hpp" | |
38 #include "prims/privilegedStack.hpp" | |
39 #include "runtime/arguments.hpp" | |
40 #include "runtime/frame.inline.hpp" | |
41 #include "runtime/interfaceSupport.hpp" | |
42 #include "runtime/java.hpp" | |
43 #include "runtime/javaCalls.hpp" | |
44 #include "runtime/mutexLocker.hpp" | |
45 #include "runtime/os.hpp" | |
46 #include "runtime/stubRoutines.hpp" | |
47 #include "services/attachListener.hpp" | |
48 #include "services/threadService.hpp" | |
49 #include "utilities/defaultStream.hpp" | |
50 #include "utilities/events.hpp" | |
51 #ifdef TARGET_OS_FAMILY_linux | |
52 # include "os_linux.inline.hpp" | |
53 # include "thread_linux.inline.hpp" | |
54 #endif | |
55 #ifdef TARGET_OS_FAMILY_solaris | |
56 # include "os_solaris.inline.hpp" | |
57 # include "thread_solaris.inline.hpp" | |
58 #endif | |
59 #ifdef TARGET_OS_FAMILY_windows | |
60 # include "os_windows.inline.hpp" | |
61 # include "thread_windows.inline.hpp" | |
62 #endif | |
0 | 63 |
64 # include <signal.h> | |
65 | |
66 OSThread* os::_starting_thread = NULL; | |
67 address os::_polling_page = NULL; | |
68 volatile int32_t* os::_mem_serialize_page = NULL; | |
69 uintptr_t os::_serialize_page_mask = 0; | |
70 long os::_rand_seed = 1; | |
71 int os::_processor_count = 0; | |
72 size_t os::_page_sizes[os::page_sizes_max]; | |
73 | |
74 #ifndef PRODUCT | |
2250 | 75 julong os::num_mallocs = 0; // # of calls to malloc/realloc |
76 julong os::alloc_bytes = 0; // # of bytes allocated | |
77 julong os::num_frees = 0; // # of calls to free | |
78 julong os::free_bytes = 0; // # of bytes freed | |
0 | 79 #endif |
80 | |
81 // Fill in buffer with current local time as an ISO-8601 string. | |
82 // E.g., yyyy-mm-ddThh:mm:ss-zzzz. | |
83 // Returns buffer, or NULL if it failed. | |
84 // This would mostly be a call to | |
85 // strftime(...., "%Y-%m-%d" "T" "%H:%M:%S" "%z", ....) | |
86 // except that on Windows the %z behaves badly, so we do it ourselves. | |
87 // Also, people wanted milliseconds on there, | |
88 // and strftime doesn't do milliseconds. | |
89 char* os::iso8601_time(char* buffer, size_t buffer_length) { | |
90 // Output will be of the form "YYYY-MM-DDThh:mm:ss.mmm+zzzz\0" | |
91 // 1 2 | |
92 // 12345678901234567890123456789 | |
93 static const char* iso8601_format = | |
94 "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d"; | |
95 static const size_t needed_buffer = 29; | |
96 | |
97 // Sanity check the arguments | |
98 if (buffer == NULL) { | |
99 assert(false, "NULL buffer"); | |
100 return NULL; | |
101 } | |
102 if (buffer_length < needed_buffer) { | |
103 assert(false, "buffer_length too small"); | |
104 return NULL; | |
105 } | |
106 // Get the current time | |
61 | 107 jlong milliseconds_since_19700101 = javaTimeMillis(); |
0 | 108 const int milliseconds_per_microsecond = 1000; |
109 const time_t seconds_since_19700101 = | |
110 milliseconds_since_19700101 / milliseconds_per_microsecond; | |
111 const int milliseconds_after_second = | |
112 milliseconds_since_19700101 % milliseconds_per_microsecond; | |
113 // Convert the time value to a tm and timezone variable | |
548
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
477
diff
changeset
|
114 struct tm time_struct; |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
477
diff
changeset
|
115 if (localtime_pd(&seconds_since_19700101, &time_struct) == NULL) { |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
477
diff
changeset
|
116 assert(false, "Failed localtime_pd"); |
0 | 117 return NULL; |
118 } | |
119 const time_t zone = timezone; | |
120 | |
121 // If daylight savings time is in effect, | |
122 // we are 1 hour East of our time zone | |
123 const time_t seconds_per_minute = 60; | |
124 const time_t minutes_per_hour = 60; | |
125 const time_t seconds_per_hour = seconds_per_minute * minutes_per_hour; | |
126 time_t UTC_to_local = zone; | |
127 if (time_struct.tm_isdst > 0) { | |
128 UTC_to_local = UTC_to_local - seconds_per_hour; | |
129 } | |
130 // Compute the time zone offset. | |
548
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
477
diff
changeset
|
131 // localtime_pd() sets timezone to the difference (in seconds) |
0 | 132 // between UTC and and local time. |
133 // ISO 8601 says we need the difference between local time and UTC, | |
548
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
477
diff
changeset
|
134 // we change the sign of the localtime_pd() result. |
0 | 135 const time_t local_to_UTC = -(UTC_to_local); |
136 // Then we have to figure out if if we are ahead (+) or behind (-) UTC. | |
137 char sign_local_to_UTC = '+'; | |
138 time_t abs_local_to_UTC = local_to_UTC; | |
139 if (local_to_UTC < 0) { | |
140 sign_local_to_UTC = '-'; | |
141 abs_local_to_UTC = -(abs_local_to_UTC); | |
142 } | |
143 // Convert time zone offset seconds to hours and minutes. | |
144 const time_t zone_hours = (abs_local_to_UTC / seconds_per_hour); | |
145 const time_t zone_min = | |
146 ((abs_local_to_UTC % seconds_per_hour) / seconds_per_minute); | |
147 | |
148 // Print an ISO 8601 date and time stamp into the buffer | |
149 const int year = 1900 + time_struct.tm_year; | |
150 const int month = 1 + time_struct.tm_mon; | |
151 const int printed = jio_snprintf(buffer, buffer_length, iso8601_format, | |
152 year, | |
153 month, | |
154 time_struct.tm_mday, | |
155 time_struct.tm_hour, | |
156 time_struct.tm_min, | |
157 time_struct.tm_sec, | |
158 milliseconds_after_second, | |
159 sign_local_to_UTC, | |
160 zone_hours, | |
161 zone_min); | |
162 if (printed == 0) { | |
163 assert(false, "Failed jio_printf"); | |
164 return NULL; | |
165 } | |
166 return buffer; | |
167 } | |
168 | |
169 OSReturn os::set_priority(Thread* thread, ThreadPriority p) { | |
170 #ifdef ASSERT | |
171 if (!(!thread->is_Java_thread() || | |
172 Thread::current() == thread || | |
173 Threads_lock->owned_by_self() | |
174 || thread->is_Compiler_thread() | |
175 )) { | |
176 assert(false, "possibility of dangling Thread pointer"); | |
177 } | |
178 #endif | |
179 | |
180 if (p >= MinPriority && p <= MaxPriority) { | |
181 int priority = java_to_os_priority[p]; | |
182 return set_native_priority(thread, priority); | |
183 } else { | |
184 assert(false, "Should not happen"); | |
185 return OS_ERR; | |
186 } | |
187 } | |
188 | |
189 | |
190 OSReturn os::get_priority(const Thread* const thread, ThreadPriority& priority) { | |
191 int p; | |
192 int os_prio; | |
193 OSReturn ret = get_native_priority(thread, &os_prio); | |
194 if (ret != OS_OK) return ret; | |
195 | |
196 for (p = MaxPriority; p > MinPriority && java_to_os_priority[p] > os_prio; p--) ; | |
197 priority = (ThreadPriority)p; | |
198 return OS_OK; | |
199 } | |
200 | |
201 | |
202 // --------------------- sun.misc.Signal (optional) --------------------- | |
203 | |
204 | |
205 // SIGBREAK is sent by the keyboard to query the VM state | |
206 #ifndef SIGBREAK | |
207 #define SIGBREAK SIGQUIT | |
208 #endif | |
209 | |
210 // sigexitnum_pd is a platform-specific special signal used for terminating the Signal thread. | |
211 | |
212 | |
213 static void signal_thread_entry(JavaThread* thread, TRAPS) { | |
214 os::set_priority(thread, NearMaxPriority); | |
215 while (true) { | |
216 int sig; | |
217 { | |
218 // FIXME : Currently we have not decieded what should be the status | |
219 // for this java thread blocked here. Once we decide about | |
220 // that we should fix this. | |
221 sig = os::signal_wait(); | |
222 } | |
223 if (sig == os::sigexitnum_pd()) { | |
224 // Terminate the signal thread | |
225 return; | |
226 } | |
227 | |
228 switch (sig) { | |
229 case SIGBREAK: { | |
230 // Check if the signal is a trigger to start the Attach Listener - in that | |
231 // case don't print stack traces. | |
232 if (!DisableAttachMechanism && AttachListener::is_init_trigger()) { | |
233 continue; | |
234 } | |
235 // Print stack traces | |
236 // Any SIGBREAK operations added here should make sure to flush | |
237 // the output stream (e.g. tty->flush()) after output. See 4803766. | |
238 // Each module also prints an extra carriage return after its output. | |
239 VM_PrintThreads op; | |
240 VMThread::execute(&op); | |
241 VM_PrintJNI jni_op; | |
242 VMThread::execute(&jni_op); | |
243 VM_FindDeadlocks op1(tty); | |
244 VMThread::execute(&op1); | |
245 Universe::print_heap_at_SIGBREAK(); | |
246 if (PrintClassHistogram) { | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
548
diff
changeset
|
247 VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */, |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
548
diff
changeset
|
248 true /* need_prologue */); |
0 | 249 VMThread::execute(&op1); |
250 } | |
251 if (JvmtiExport::should_post_data_dump()) { | |
252 JvmtiExport::post_data_dump(); | |
253 } | |
254 break; | |
255 } | |
256 default: { | |
257 // Dispatch the signal to java | |
258 HandleMark hm(THREAD); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
259 klassOop k = SystemDictionary::resolve_or_null(vmSymbols::sun_misc_Signal(), THREAD); |
0 | 260 KlassHandle klass (THREAD, k); |
261 if (klass.not_null()) { | |
262 JavaValue result(T_VOID); | |
263 JavaCallArguments args; | |
264 args.push_int(sig); | |
265 JavaCalls::call_static( | |
266 &result, | |
267 klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
268 vmSymbols::dispatch_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
269 vmSymbols::int_void_signature(), |
0 | 270 &args, |
271 THREAD | |
272 ); | |
273 } | |
274 if (HAS_PENDING_EXCEPTION) { | |
275 // tty is initialized early so we don't expect it to be null, but | |
276 // if it is we can't risk doing an initialization that might | |
277 // trigger additional out-of-memory conditions | |
278 if (tty != NULL) { | |
279 char klass_name[256]; | |
280 char tmp_sig_name[16]; | |
281 const char* sig_name = "UNKNOWN"; | |
282 instanceKlass::cast(PENDING_EXCEPTION->klass())-> | |
283 name()->as_klass_external_name(klass_name, 256); | |
284 if (os::exception_name(sig, tmp_sig_name, 16) != NULL) | |
285 sig_name = tmp_sig_name; | |
286 warning("Exception %s occurred dispatching signal %s to handler" | |
287 "- the VM may need to be forcibly terminated", | |
288 klass_name, sig_name ); | |
289 } | |
290 CLEAR_PENDING_EXCEPTION; | |
291 } | |
292 } | |
293 } | |
294 } | |
295 } | |
296 | |
297 | |
298 void os::signal_init() { | |
299 if (!ReduceSignalUsage) { | |
300 // Setup JavaThread for processing signals | |
301 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
302 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); |
0 | 303 instanceKlassHandle klass (THREAD, k); |
304 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); | |
305 | |
306 const char thread_name[] = "Signal Dispatcher"; | |
307 Handle string = java_lang_String::create_from_str(thread_name, CHECK); | |
308 | |
309 // Initialize thread_oop to put it into the system threadGroup | |
310 Handle thread_group (THREAD, Universe::system_thread_group()); | |
311 JavaValue result(T_VOID); | |
312 JavaCalls::call_special(&result, thread_oop, | |
313 klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
314 vmSymbols::object_initializer_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
315 vmSymbols::threadgroup_string_void_signature(), |
0 | 316 thread_group, |
317 string, | |
318 CHECK); | |
319 | |
1142 | 320 KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass()); |
0 | 321 JavaCalls::call_special(&result, |
322 thread_group, | |
323 group, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
324 vmSymbols::add_method_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1980
diff
changeset
|
325 vmSymbols::thread_void_signature(), |
0 | 326 thread_oop, // ARG 1 |
327 CHECK); | |
328 | |
329 os::signal_init_pd(); | |
330 | |
331 { MutexLocker mu(Threads_lock); | |
332 JavaThread* signal_thread = new JavaThread(&signal_thread_entry); | |
333 | |
334 // At this point it may be possible that no osthread was created for the | |
335 // JavaThread due to lack of memory. We would have to throw an exception | |
336 // in that case. However, since this must work and we do not allow | |
337 // exceptions anyway, check and abort if this fails. | |
338 if (signal_thread == NULL || signal_thread->osthread() == NULL) { | |
339 vm_exit_during_initialization("java.lang.OutOfMemoryError", | |
340 "unable to create new native thread"); | |
341 } | |
342 | |
343 java_lang_Thread::set_thread(thread_oop(), signal_thread); | |
344 java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); | |
345 java_lang_Thread::set_daemon(thread_oop()); | |
346 | |
347 signal_thread->set_threadObj(thread_oop()); | |
348 Threads::add(signal_thread); | |
349 Thread::start(signal_thread); | |
350 } | |
351 // Handle ^BREAK | |
352 os::signal(SIGBREAK, os::user_handler()); | |
353 } | |
354 } | |
355 | |
356 | |
357 void os::terminate_signal_thread() { | |
358 if (!ReduceSignalUsage) | |
359 signal_notify(sigexitnum_pd()); | |
360 } | |
361 | |
362 | |
363 // --------------------- loading libraries --------------------- | |
364 | |
365 typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *); | |
366 extern struct JavaVM_ main_vm; | |
367 | |
368 static void* _native_java_library = NULL; | |
369 | |
370 void* os::native_java_library() { | |
371 if (_native_java_library == NULL) { | |
372 char buffer[JVM_MAXPATHLEN]; | |
373 char ebuf[1024]; | |
374 | |
242 | 375 // Try to load verify dll first. In 1.3 java dll depends on it and is not |
376 // always able to find it when the loading executable is outside the JDK. | |
0 | 377 // In order to keep working with 1.2 we ignore any loading errors. |
242 | 378 dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"); |
379 dll_load(buffer, ebuf, sizeof(ebuf)); | |
0 | 380 |
381 // Load java dll | |
242 | 382 dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java"); |
383 _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf)); | |
0 | 384 if (_native_java_library == NULL) { |
385 vm_exit_during_initialization("Unable to load native library", ebuf); | |
386 } | |
242 | 387 } |
388 static jboolean onLoaded = JNI_FALSE; | |
389 if (onLoaded) { | |
390 // We may have to wait to fire OnLoad until TLS is initialized. | |
391 if (ThreadLocalStorage::is_initialized()) { | |
392 // The JNI_OnLoad handling is normally done by method load in | |
393 // java.lang.ClassLoader$NativeLibrary, but the VM loads the base library | |
394 // explicitly so we have to check for JNI_OnLoad as well | |
395 const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; | |
396 JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR( | |
397 JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0])); | |
398 if (JNI_OnLoad != NULL) { | |
399 JavaThread* thread = JavaThread::current(); | |
400 ThreadToNativeFromVM ttn(thread); | |
401 HandleMark hm(thread); | |
402 jint ver = (*JNI_OnLoad)(&main_vm, NULL); | |
403 onLoaded = JNI_TRUE; | |
404 if (!Threads::is_supported_jni_version_including_1_1(ver)) { | |
405 vm_exit_during_initialization("Unsupported JNI version"); | |
406 } | |
0 | 407 } |
408 } | |
409 } | |
410 return _native_java_library; | |
411 } | |
412 | |
413 // --------------------- heap allocation utilities --------------------- | |
414 | |
415 char *os::strdup(const char *str) { | |
416 size_t size = strlen(str); | |
417 char *dup_str = (char *)malloc(size + 1); | |
418 if (dup_str == NULL) return NULL; | |
419 strcpy(dup_str, str); | |
420 return dup_str; | |
421 } | |
422 | |
423 | |
424 | |
425 #ifdef ASSERT | |
426 #define space_before (MallocCushion + sizeof(double)) | |
427 #define space_after MallocCushion | |
428 #define size_addr_from_base(p) (size_t*)(p + space_before - sizeof(size_t)) | |
429 #define size_addr_from_obj(p) ((size_t*)p - 1) | |
430 // MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly | |
431 // NB: cannot be debug variable, because these aren't set from the command line until | |
432 // *after* the first few allocs already happened | |
433 #define MallocCushion 16 | |
434 #else | |
435 #define space_before 0 | |
436 #define space_after 0 | |
437 #define size_addr_from_base(p) should not use w/o ASSERT | |
438 #define size_addr_from_obj(p) should not use w/o ASSERT | |
439 #define MallocCushion 0 | |
440 #endif | |
441 #define paranoid 0 /* only set to 1 if you suspect checking code has bug */ | |
442 | |
443 #ifdef ASSERT | |
444 inline size_t get_size(void* obj) { | |
445 size_t size = *size_addr_from_obj(obj); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1142
diff
changeset
|
446 if (size < 0) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1142
diff
changeset
|
447 fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten (" |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1142
diff
changeset
|
448 SIZE_FORMAT ")", obj, size)); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1142
diff
changeset
|
449 } |
0 | 450 return size; |
451 } | |
452 | |
453 u_char* find_cushion_backwards(u_char* start) { | |
454 u_char* p = start; | |
455 while (p[ 0] != badResourceValue || p[-1] != badResourceValue || | |
456 p[-2] != badResourceValue || p[-3] != badResourceValue) p--; | |
457 // ok, we have four consecutive marker bytes; find start | |
458 u_char* q = p - 4; | |
459 while (*q == badResourceValue) q--; | |
460 return q + 1; | |
461 } | |
462 | |
463 u_char* find_cushion_forwards(u_char* start) { | |
464 u_char* p = start; | |
465 while (p[0] != badResourceValue || p[1] != badResourceValue || | |
466 p[2] != badResourceValue || p[3] != badResourceValue) p++; | |
467 // ok, we have four consecutive marker bytes; find end of cushion | |
468 u_char* q = p + 4; | |
469 while (*q == badResourceValue) q++; | |
470 return q - MallocCushion; | |
471 } | |
472 | |
473 void print_neighbor_blocks(void* ptr) { | |
474 // find block allocated before ptr (not entirely crash-proof) | |
475 if (MallocCushion < 4) { | |
476 tty->print_cr("### cannot find previous block (MallocCushion < 4)"); | |
477 return; | |
478 } | |
479 u_char* start_of_this_block = (u_char*)ptr - space_before; | |
480 u_char* end_of_prev_block_data = start_of_this_block - space_after -1; | |
481 // look for cushion in front of prev. block | |
482 u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data); | |
483 ptrdiff_t size = *size_addr_from_base(start_of_prev_block); | |
484 u_char* obj = start_of_prev_block + space_before; | |
485 if (size <= 0 ) { | |
486 // start is bad; mayhave been confused by OS data inbetween objects | |
487 // search one more backwards | |
488 start_of_prev_block = find_cushion_backwards(start_of_prev_block); | |
489 size = *size_addr_from_base(start_of_prev_block); | |
490 obj = start_of_prev_block + space_before; | |
491 } | |
492 | |
493 if (start_of_prev_block + space_before + size + space_after == start_of_this_block) { | |
2250 | 494 tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size); |
0 | 495 } else { |
2250 | 496 tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size); |
0 | 497 } |
498 | |
499 // now find successor block | |
500 u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after; | |
501 start_of_next_block = find_cushion_forwards(start_of_next_block); | |
502 u_char* next_obj = start_of_next_block + space_before; | |
503 ptrdiff_t next_size = *size_addr_from_base(start_of_next_block); | |
504 if (start_of_next_block[0] == badResourceValue && | |
505 start_of_next_block[1] == badResourceValue && | |
506 start_of_next_block[2] == badResourceValue && | |
507 start_of_next_block[3] == badResourceValue) { | |
2250 | 508 tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size); |
0 | 509 } else { |
2250 | 510 tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size); |
0 | 511 } |
512 } | |
513 | |
514 | |
515 void report_heap_error(void* memblock, void* bad, const char* where) { | |
2250 | 516 tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees); |
517 tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock); | |
0 | 518 print_neighbor_blocks(memblock); |
519 fatal("memory stomping error"); | |
520 } | |
521 | |
522 void verify_block(void* memblock) { | |
523 size_t size = get_size(memblock); | |
524 if (MallocCushion) { | |
525 u_char* ptr = (u_char*)memblock - space_before; | |
526 for (int i = 0; i < MallocCushion; i++) { | |
527 if (ptr[i] != badResourceValue) { | |
528 report_heap_error(memblock, ptr+i, "in front of"); | |
529 } | |
530 } | |
531 u_char* end = (u_char*)memblock + size + space_after; | |
532 for (int j = -MallocCushion; j < 0; j++) { | |
533 if (end[j] != badResourceValue) { | |
534 report_heap_error(memblock, end+j, "after"); | |
535 } | |
536 } | |
537 } | |
538 } | |
539 #endif | |
540 | |
541 void* os::malloc(size_t size) { | |
2250 | 542 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); |
543 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); | |
0 | 544 |
545 if (size == 0) { | |
546 // return a valid pointer if size is zero | |
547 // if NULL is returned the calling functions assume out of memory. | |
548 size = 1; | |
549 } | |
550 | |
551 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | |
552 u_char* ptr = (u_char*)::malloc(size + space_before + space_after); | |
553 #ifdef ASSERT | |
554 if (ptr == NULL) return NULL; | |
555 if (MallocCushion) { | |
556 for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue; | |
557 u_char* end = ptr + space_before + size; | |
558 for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad; | |
559 for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue; | |
560 } | |
561 // put size just before data | |
562 *size_addr_from_base(ptr) = size; | |
563 #endif | |
564 u_char* memblock = ptr + space_before; | |
565 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | |
2250 | 566 tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); |
0 | 567 breakpoint(); |
568 } | |
569 debug_only(if (paranoid) verify_block(memblock)); | |
2250 | 570 if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock); |
0 | 571 return memblock; |
572 } | |
573 | |
574 | |
575 void* os::realloc(void *memblock, size_t size) { | |
576 #ifndef ASSERT | |
2250 | 577 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); |
578 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); | |
0 | 579 return ::realloc(memblock, size); |
580 #else | |
581 if (memblock == NULL) { | |
2250 | 582 return malloc(size); |
0 | 583 } |
584 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | |
2250 | 585 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock); |
0 | 586 breakpoint(); |
587 } | |
588 verify_block(memblock); | |
589 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | |
590 if (size == 0) return NULL; | |
591 // always move the block | |
592 void* ptr = malloc(size); | |
2250 | 593 if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); |
0 | 594 // Copy to new memory if malloc didn't fail |
595 if ( ptr != NULL ) { | |
596 memcpy(ptr, memblock, MIN2(size, get_size(memblock))); | |
597 if (paranoid) verify_block(ptr); | |
598 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { | |
2250 | 599 tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr); |
0 | 600 breakpoint(); |
601 } | |
602 free(memblock); | |
603 } | |
604 return ptr; | |
605 #endif | |
606 } | |
607 | |
608 | |
609 void os::free(void *memblock) { | |
2250 | 610 NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); |
0 | 611 #ifdef ASSERT |
612 if (memblock == NULL) return; | |
613 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | |
2250 | 614 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock); |
0 | 615 breakpoint(); |
616 } | |
617 verify_block(memblock); | |
618 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | |
619 // Added by detlefs. | |
620 if (MallocCushion) { | |
621 u_char* ptr = (u_char*)memblock - space_before; | |
622 for (u_char* p = ptr; p < ptr + MallocCushion; p++) { | |
623 guarantee(*p == badResourceValue, | |
624 "Thing freed should be malloc result."); | |
625 *p = (u_char)freeBlockPad; | |
626 } | |
627 size_t size = get_size(memblock); | |
2250 | 628 inc_stat_counter(&free_bytes, size); |
0 | 629 u_char* end = ptr + space_before + size; |
630 for (u_char* q = end; q < end + MallocCushion; q++) { | |
631 guarantee(*q == badResourceValue, | |
632 "Thing freed should be malloc result."); | |
633 *q = (u_char)freeBlockPad; | |
634 } | |
2250 | 635 if (PrintMalloc && tty != NULL) |
2333
f767174aac14
7021653: Parfait issue in hotspot/src/share/vm/oops/methodDataOops.hpp
coleenp
parents:
2250
diff
changeset
|
636 fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock); |
2250 | 637 } else if (PrintMalloc && tty != NULL) { |
638 // tty->print_cr("os::free %p", memblock); | |
2333
f767174aac14
7021653: Parfait issue in hotspot/src/share/vm/oops/methodDataOops.hpp
coleenp
parents:
2250
diff
changeset
|
639 fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock); |
0 | 640 } |
641 #endif | |
642 ::free((char*)memblock - space_before); | |
643 } | |
644 | |
645 void os::init_random(long initval) { | |
646 _rand_seed = initval; | |
647 } | |
648 | |
649 | |
650 long os::random() { | |
651 /* standard, well-known linear congruential random generator with | |
652 * next_rand = (16807*seed) mod (2**31-1) | |
653 * see | |
654 * (1) "Random Number Generators: Good Ones Are Hard to Find", | |
655 * S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988), | |
656 * (2) "Two Fast Implementations of the 'Minimal Standard' Random | |
657 * Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), pp. 87-88. | |
658 */ | |
659 const long a = 16807; | |
660 const unsigned long m = 2147483647; | |
661 const long q = m / a; assert(q == 127773, "weird math"); | |
662 const long r = m % a; assert(r == 2836, "weird math"); | |
663 | |
664 // compute az=2^31p+q | |
665 unsigned long lo = a * (long)(_rand_seed & 0xFFFF); | |
666 unsigned long hi = a * (long)((unsigned long)_rand_seed >> 16); | |
667 lo += (hi & 0x7FFF) << 16; | |
668 | |
669 // if q overflowed, ignore the overflow and increment q | |
670 if (lo > m) { | |
671 lo &= m; | |
672 ++lo; | |
673 } | |
674 lo += hi >> 15; | |
675 | |
676 // if (p+q) overflowed, ignore the overflow and increment (p+q) | |
677 if (lo > m) { | |
678 lo &= m; | |
679 ++lo; | |
680 } | |
681 return (_rand_seed = lo); | |
682 } | |
683 | |
684 // The INITIALIZED state is distinguished from the SUSPENDED state because the | |
685 // conditions in which a thread is first started are different from those in which | |
686 // a suspension is resumed. These differences make it hard for us to apply the | |
687 // tougher checks when starting threads that we want to do when resuming them. | |
688 // However, when start_thread is called as a result of Thread.start, on a Java | |
689 // thread, the operation is synchronized on the Java Thread object. So there | |
690 // cannot be a race to start the thread and hence for the thread to exit while | |
691 // we are working on it. Non-Java threads that start Java threads either have | |
692 // to do so in a context in which races are impossible, or should do appropriate | |
693 // locking. | |
694 | |
695 void os::start_thread(Thread* thread) { | |
696 // guard suspend/resume | |
697 MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag); | |
698 OSThread* osthread = thread->osthread(); | |
699 osthread->set_state(RUNNABLE); | |
700 pd_start_thread(thread); | |
701 } | |
702 | |
703 //--------------------------------------------------------------------------- | |
704 // Helper functions for fatal error handler | |
705 | |
706 void os::print_hex_dump(outputStream* st, address start, address end, int unitsize) { | |
707 assert(unitsize == 1 || unitsize == 2 || unitsize == 4 || unitsize == 8, "just checking"); | |
708 | |
709 int cols = 0; | |
710 int cols_per_line = 0; | |
711 switch (unitsize) { | |
712 case 1: cols_per_line = 16; break; | |
713 case 2: cols_per_line = 8; break; | |
714 case 4: cols_per_line = 4; break; | |
715 case 8: cols_per_line = 2; break; | |
716 default: return; | |
717 } | |
718 | |
719 address p = start; | |
720 st->print(PTR_FORMAT ": ", start); | |
721 while (p < end) { | |
722 switch (unitsize) { | |
723 case 1: st->print("%02x", *(u1*)p); break; | |
724 case 2: st->print("%04x", *(u2*)p); break; | |
725 case 4: st->print("%08x", *(u4*)p); break; | |
726 case 8: st->print("%016" FORMAT64_MODIFIER "x", *(u8*)p); break; | |
727 } | |
728 p += unitsize; | |
729 cols++; | |
730 if (cols >= cols_per_line && p < end) { | |
731 cols = 0; | |
732 st->cr(); | |
733 st->print(PTR_FORMAT ": ", p); | |
734 } else { | |
735 st->print(" "); | |
736 } | |
737 } | |
738 st->cr(); | |
739 } | |
740 | |
741 void os::print_environment_variables(outputStream* st, const char** env_list, | |
742 char* buffer, int len) { | |
743 if (env_list) { | |
744 st->print_cr("Environment Variables:"); | |
745 | |
746 for (int i = 0; env_list[i] != NULL; i++) { | |
747 if (getenv(env_list[i], buffer, len)) { | |
748 st->print(env_list[i]); | |
749 st->print("="); | |
750 st->print_cr(buffer); | |
751 } | |
752 } | |
753 } | |
754 } | |
755 | |
756 void os::print_cpu_info(outputStream* st) { | |
757 // cpu | |
758 st->print("CPU:"); | |
759 st->print("total %d", os::processor_count()); | |
760 // It's not safe to query number of active processors after crash | |
761 // st->print("(active %d)", os::active_processor_count()); | |
762 st->print(" %s", VM_Version::cpu_features()); | |
763 st->cr(); | |
3800
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
2469
diff
changeset
|
764 pd_print_cpu_info(st); |
0 | 765 } |
766 | |
767 void os::print_date_and_time(outputStream *st) { | |
768 time_t tloc; | |
769 (void)time(&tloc); | |
770 st->print("time: %s", ctime(&tloc)); // ctime adds newline. | |
771 | |
772 double t = os::elapsedTime(); | |
773 // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in | |
774 // Linux. Must be a bug in glibc ? Workaround is to round "t" to int | |
775 // before printf. We lost some precision, but who cares? | |
776 st->print_cr("elapsed time: %d seconds", (int)t); | |
777 } | |
778 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
779 // moved from debug.cpp (used to be find()) but still called from there |
1907 | 780 // The verbose parameter is only set by the debug code in one case |
781 void os::print_location(outputStream* st, intptr_t x, bool verbose) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
782 address addr = (address)x; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
783 CodeBlob* b = CodeCache::find_blob_unsafe(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
784 if (b != NULL) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
785 if (b->is_buffer_blob()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
786 // the interpreter is generated into a buffer blob |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
787 InterpreterCodelet* i = Interpreter::codelet_containing(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
788 if (i != NULL) { |
1907 | 789 st->print_cr(INTPTR_FORMAT " is an Interpreter codelet", addr); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
790 i->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
791 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
792 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
793 if (Interpreter::contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
794 st->print_cr(INTPTR_FORMAT " is pointing into interpreter code" |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
795 " (not bytecode specific)", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
796 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
797 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
798 // |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
799 if (AdapterHandlerLibrary::contains(b)) { |
1907 | 800 st->print_cr(INTPTR_FORMAT " is an AdapterHandler", addr); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
801 AdapterHandlerLibrary::print_handler_on(st, b); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
802 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
803 // the stubroutines are generated into a buffer blob |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
804 StubCodeDesc* d = StubCodeDesc::desc_for(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
805 if (d != NULL) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
806 d->print_on(st); |
1907 | 807 if (verbose) st->cr(); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
808 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
809 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
810 if (StubRoutines::contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
811 st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) " |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
812 "stub routine", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
813 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
814 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
815 // the InlineCacheBuffer is using stubs generated into a buffer blob |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
816 if (InlineCacheBuffer::contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
817 st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
818 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
819 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
820 VtableStub* v = VtableStubs::stub_containing(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
821 if (v != NULL) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
822 v->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
823 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
824 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
825 } |
1907 | 826 if (verbose && b->is_nmethod()) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
827 ResourceMark rm; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
828 st->print("%#p: Compiled ", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
829 ((nmethod*)b)->method()->print_value_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
830 st->print(" = (CodeBlob*)" INTPTR_FORMAT, b); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
831 st->cr(); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
832 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
833 } |
1907 | 834 st->print(INTPTR_FORMAT " ", b); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
835 if ( b->is_nmethod()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
836 if (b->is_zombie()) { |
1907 | 837 st->print_cr("is zombie nmethod"); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
838 } else if (b->is_not_entrant()) { |
1907 | 839 st->print_cr("is non-entrant nmethod"); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
840 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
841 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
842 b->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
843 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
844 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
845 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
846 if (Universe::heap()->is_in(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
847 HeapWord* p = Universe::heap()->block_start(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
848 bool print = false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
849 // If we couldn't find it it just may mean that heap wasn't parseable |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
850 // See if we were just given an oop directly |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
851 if (p != NULL && Universe::heap()->block_is_obj(p)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
852 print = true; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
853 } else if (p == NULL && ((oopDesc*)addr)->is_oop()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
854 p = (HeapWord*) addr; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
855 print = true; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
856 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
857 if (print) { |
1907 | 858 st->print_cr(INTPTR_FORMAT " is an oop", addr); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
859 oop(p)->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
860 if (p != (HeapWord*)x && oop(p)->is_constMethod() && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
861 constMethodOop(p)->contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
862 Thread *thread = Thread::current(); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
863 HandleMark hm(thread); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
864 methodHandle mh (thread, constMethodOop(p)->method()); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
865 if (!mh->is_native()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
866 st->print_cr("bci_from(%p) = %d; print_codes():", |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
867 addr, mh->bci_from(address(x))); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
868 mh->print_codes_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
869 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
870 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
871 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
872 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
873 } else { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
874 if (Universe::heap()->is_in_reserved(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
875 st->print_cr(INTPTR_FORMAT " is an unallocated location " |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
876 "in the heap", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
877 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
878 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
879 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
880 if (JNIHandles::is_global_handle((jobject) addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
881 st->print_cr(INTPTR_FORMAT " is a global jni handle", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
882 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
883 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
884 if (JNIHandles::is_weak_global_handle((jobject) addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
885 st->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
886 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
887 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
888 #ifndef PRODUCT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
889 // we don't keep the block list in product mode |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
890 if (JNIHandleBlock::any_contains((jobject) addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
891 st->print_cr(INTPTR_FORMAT " is a local jni handle", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
892 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
893 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
894 #endif |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
895 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
896 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
897 // Check for privilege stack |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
898 if (thread->privileged_stack_top() != NULL && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
899 thread->privileged_stack_top()->contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
900 st->print_cr(INTPTR_FORMAT " is pointing into the privilege stack " |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
901 "for thread: " INTPTR_FORMAT, addr, thread); |
1907 | 902 if (verbose) thread->print_on(st); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
903 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
904 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
905 // If the addr is a java thread print information about that. |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
906 if (addr == (address)thread) { |
1907 | 907 if (verbose) { |
908 thread->print_on(st); | |
909 } else { | |
910 st->print_cr(INTPTR_FORMAT " is a thread", addr); | |
911 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
912 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
913 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
914 // If the addr is in the stack region for this thread then report that |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
915 // and print thread info |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
916 if (thread->stack_base() >= addr && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
917 addr > (thread->stack_base() - thread->stack_size())) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
918 st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: " |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
919 INTPTR_FORMAT, addr, thread); |
1907 | 920 if (verbose) thread->print_on(st); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
921 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
922 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
923 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
924 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
925 // Try an OS specific find |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
926 if (os::find(addr, st)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
927 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
928 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
929 |
1907 | 930 st->print_cr(INTPTR_FORMAT " is an unknown value", addr); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
931 } |
0 | 932 |
933 // Looks like all platforms except IA64 can use the same function to check | |
934 // if C stack is walkable beyond current frame. The check for fp() is not | |
935 // necessary on Sparc, but it's harmless. | |
936 bool os::is_first_C_frame(frame* fr) { | |
937 #ifdef IA64 | |
938 // In order to walk native frames on Itanium, we need to access the unwind | |
939 // table, which is inside ELF. We don't want to parse ELF after fatal error, | |
940 // so return true for IA64. If we need to support C stack walking on IA64, | |
941 // this function needs to be moved to CPU specific files, as fp() on IA64 | |
942 // is register stack, which grows towards higher memory address. | |
943 return true; | |
944 #endif | |
945 | |
946 // Load up sp, fp, sender sp and sender fp, check for reasonable values. | |
947 // Check usp first, because if that's bad the other accessors may fault | |
948 // on some architectures. Ditto ufp second, etc. | |
949 uintptr_t fp_align_mask = (uintptr_t)(sizeof(address)-1); | |
950 // sp on amd can be 32 bit aligned. | |
951 uintptr_t sp_align_mask = (uintptr_t)(sizeof(int)-1); | |
952 | |
953 uintptr_t usp = (uintptr_t)fr->sp(); | |
954 if ((usp & sp_align_mask) != 0) return true; | |
955 | |
956 uintptr_t ufp = (uintptr_t)fr->fp(); | |
957 if ((ufp & fp_align_mask) != 0) return true; | |
958 | |
959 uintptr_t old_sp = (uintptr_t)fr->sender_sp(); | |
960 if ((old_sp & sp_align_mask) != 0) return true; | |
961 if (old_sp == 0 || old_sp == (uintptr_t)-1) return true; | |
962 | |
963 uintptr_t old_fp = (uintptr_t)fr->link(); | |
964 if ((old_fp & fp_align_mask) != 0) return true; | |
965 if (old_fp == 0 || old_fp == (uintptr_t)-1 || old_fp == ufp) return true; | |
966 | |
967 // stack grows downwards; if old_fp is below current fp or if the stack | |
968 // frame is too large, either the stack is corrupted or fp is not saved | |
969 // on stack (i.e. on x86, ebp may be used as general register). The stack | |
970 // is not walkable beyond current frame. | |
971 if (old_fp < ufp) return true; | |
972 if (old_fp - ufp > 64 * K) return true; | |
973 | |
974 return false; | |
975 } | |
976 | |
977 #ifdef ASSERT | |
978 extern "C" void test_random() { | |
979 const double m = 2147483647; | |
980 double mean = 0.0, variance = 0.0, t; | |
981 long reps = 10000; | |
982 unsigned long seed = 1; | |
983 | |
984 tty->print_cr("seed %ld for %ld repeats...", seed, reps); | |
985 os::init_random(seed); | |
986 long num; | |
987 for (int k = 0; k < reps; k++) { | |
988 num = os::random(); | |
989 double u = (double)num / m; | |
990 assert(u >= 0.0 && u <= 1.0, "bad random number!"); | |
991 | |
992 // calculate mean and variance of the random sequence | |
993 mean += u; | |
994 variance += (u*u); | |
995 } | |
996 mean /= reps; | |
997 variance /= (reps - 1); | |
998 | |
999 assert(num == 1043618065, "bad seed"); | |
1000 tty->print_cr("mean of the 1st 10000 numbers: %f", mean); | |
1001 tty->print_cr("variance of the 1st 10000 numbers: %f", variance); | |
1002 const double eps = 0.0001; | |
1003 t = fabsd(mean - 0.5018); | |
1004 assert(t < eps, "bad mean"); | |
1005 t = (variance - 0.3355) < 0.0 ? -(variance - 0.3355) : variance - 0.3355; | |
1006 assert(t < eps, "bad variance"); | |
1007 } | |
1008 #endif | |
1009 | |
1010 | |
1011 // Set up the boot classpath. | |
1012 | |
1013 char* os::format_boot_path(const char* format_string, | |
1014 const char* home, | |
1015 int home_len, | |
1016 char fileSep, | |
1017 char pathSep) { | |
1018 assert((fileSep == '/' && pathSep == ':') || | |
1019 (fileSep == '\\' && pathSep == ';'), "unexpected seperator chars"); | |
1020 | |
1021 // Scan the format string to determine the length of the actual | |
1022 // boot classpath, and handle platform dependencies as well. | |
1023 int formatted_path_len = 0; | |
1024 const char* p; | |
1025 for (p = format_string; *p != 0; ++p) { | |
1026 if (*p == '%') formatted_path_len += home_len - 1; | |
1027 ++formatted_path_len; | |
1028 } | |
1029 | |
1030 char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1); | |
1031 if (formatted_path == NULL) { | |
1032 return NULL; | |
1033 } | |
1034 | |
1035 // Create boot classpath from format, substituting separator chars and | |
1036 // java home directory. | |
1037 char* q = formatted_path; | |
1038 for (p = format_string; *p != 0; ++p) { | |
1039 switch (*p) { | |
1040 case '%': | |
1041 strcpy(q, home); | |
1042 q += home_len; | |
1043 break; | |
1044 case '/': | |
1045 *q++ = fileSep; | |
1046 break; | |
1047 case ':': | |
1048 *q++ = pathSep; | |
1049 break; | |
1050 default: | |
1051 *q++ = *p; | |
1052 } | |
1053 } | |
1054 *q = '\0'; | |
1055 | |
1056 assert((q - formatted_path) == formatted_path_len, "formatted_path size botched"); | |
1057 return formatted_path; | |
1058 } | |
1059 | |
1060 | |
1061 bool os::set_boot_path(char fileSep, char pathSep) { | |
1062 const char* home = Arguments::get_java_home(); | |
1063 int home_len = (int)strlen(home); | |
1064 | |
1065 static const char* meta_index_dir_format = "%/lib/"; | |
1066 static const char* meta_index_format = "%/lib/meta-index"; | |
1067 char* meta_index = format_boot_path(meta_index_format, home, home_len, fileSep, pathSep); | |
1068 if (meta_index == NULL) return false; | |
1069 char* meta_index_dir = format_boot_path(meta_index_dir_format, home, home_len, fileSep, pathSep); | |
1070 if (meta_index_dir == NULL) return false; | |
1071 Arguments::set_meta_index_path(meta_index, meta_index_dir); | |
1072 | |
1073 // Any modification to the JAR-file list, for the boot classpath must be | |
1074 // aligned with install/install/make/common/Pack.gmk. Note: boot class | |
1075 // path class JARs, are stripped for StackMapTable to reduce download size. | |
1076 static const char classpath_format[] = | |
1077 "%/lib/resources.jar:" | |
1078 "%/lib/rt.jar:" | |
1079 "%/lib/sunrsasign.jar:" | |
1080 "%/lib/jsse.jar:" | |
1081 "%/lib/jce.jar:" | |
1082 "%/lib/charsets.jar:" | |
1083 "%/classes"; | |
1084 char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep); | |
1085 if (sysclasspath == NULL) return false; | |
1086 Arguments::set_sysclasspath(sysclasspath); | |
1087 | |
1088 return true; | |
1089 } | |
1090 | |
691 | 1091 /* |
1092 * Splits a path, based on its separator, the number of | |
1093 * elements is returned back in n. | |
1094 * It is the callers responsibility to: | |
1095 * a> check the value of n, and n may be 0. | |
1096 * b> ignore any empty path elements | |
1097 * c> free up the data. | |
1098 */ | |
1099 char** os::split_path(const char* path, int* n) { | |
1100 *n = 0; | |
1101 if (path == NULL || strlen(path) == 0) { | |
1102 return NULL; | |
1103 } | |
1104 const char psepchar = *os::path_separator(); | |
1105 char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1); | |
1106 if (inpath == NULL) { | |
1107 return NULL; | |
1108 } | |
1109 strncpy(inpath, path, strlen(path)); | |
1110 int count = 1; | |
1111 char* p = strchr(inpath, psepchar); | |
1112 // Get a count of elements to allocate memory | |
1113 while (p != NULL) { | |
1114 count++; | |
1115 p++; | |
1116 p = strchr(p, psepchar); | |
1117 } | |
1118 char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count); | |
1119 if (opath == NULL) { | |
1120 return NULL; | |
1121 } | |
1122 | |
1123 // do the actual splitting | |
1124 p = inpath; | |
1125 for (int i = 0 ; i < count ; i++) { | |
1126 size_t len = strcspn(p, os::path_separator()); | |
1127 if (len > JVM_MAXPATHLEN) { | |
1128 return NULL; | |
1129 } | |
1130 // allocate the string and add terminator storage | |
1131 char* s = (char*)NEW_C_HEAP_ARRAY(char, len + 1); | |
1132 if (s == NULL) { | |
1133 return NULL; | |
1134 } | |
1135 strncpy(s, p, len); | |
1136 s[len] = '\0'; | |
1137 opath[i] = s; | |
1138 p += len + 1; | |
1139 } | |
1140 FREE_C_HEAP_ARRAY(char, inpath); | |
1141 *n = count; | |
1142 return opath; | |
1143 } | |
1144 | |
0 | 1145 void os::set_memory_serialize_page(address page) { |
1146 int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); | |
1147 _mem_serialize_page = (volatile int32_t *)page; | |
1148 // We initialize the serialization page shift count here | |
1149 // We assume a cache line size of 64 bytes | |
1150 assert(SerializePageShiftCount == count, | |
1151 "thread size changed, fix SerializePageShiftCount constant"); | |
1152 set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t))); | |
1153 } | |
1154 | |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1155 static volatile intptr_t SerializePageLock = 0; |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1156 |
0 | 1157 // This method is called from signal handler when SIGSEGV occurs while the current |
1158 // thread tries to store to the "read-only" memory serialize page during state | |
1159 // transition. | |
1160 void os::block_on_serialize_page_trap() { | |
1161 if (TraceSafepoint) { | |
1162 tty->print_cr("Block until the serialize page permission restored"); | |
1163 } | |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1164 // When VMThread is holding the SerializePageLock during modifying the |
0 | 1165 // access permission of the memory serialize page, the following call |
1166 // will block until the permission of that page is restored to rw. | |
1167 // Generally, it is unsafe to manipulate locks in signal handlers, but in | |
1168 // this case, it's OK as the signal is synchronous and we know precisely when | |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1169 // it can occur. |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1170 Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page"); |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1171 Thread::muxRelease(&SerializePageLock); |
0 | 1172 } |
1173 | |
1174 // Serialize all thread state variables | |
1175 void os::serialize_thread_states() { | |
1176 // On some platforms such as Solaris & Linux, the time duration of the page | |
1177 // permission restoration is observed to be much longer than expected due to | |
1178 // scheduler starvation problem etc. To avoid the long synchronization | |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1179 // time and expensive page trap spinning, 'SerializePageLock' is used to block |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1180 // the mutator thread if such case is encountered. See bug 6546278 for details. |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1181 Thread::muxAcquire(&SerializePageLock, "serialize_thread_states"); |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
1182 os::protect_memory((char *)os::get_memory_serialize_page(), |
477
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
242
diff
changeset
|
1183 os::vm_page_size(), MEM_PROT_READ); |
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
242
diff
changeset
|
1184 os::protect_memory((char *)os::get_memory_serialize_page(), |
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
242
diff
changeset
|
1185 os::vm_page_size(), MEM_PROT_RW); |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1186 Thread::muxRelease(&SerializePageLock); |
0 | 1187 } |
1188 | |
1189 // Returns true if the current stack pointer is above the stack shadow | |
1190 // pages, false otherwise. | |
1191 | |
1192 bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) { | |
1193 assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check"); | |
1194 address sp = current_stack_pointer(); | |
1195 // Check if we have StackShadowPages above the yellow zone. This parameter | |
605 | 1196 // is dependent on the depth of the maximum VM call stack possible from |
0 | 1197 // the handler for stack overflow. 'instanceof' in the stack overflow |
1198 // handler or a println uses at least 8k stack of VM and native code | |
1199 // respectively. | |
1200 const int framesize_in_bytes = | |
1201 Interpreter::size_top_interpreter_activation(method()) * wordSize; | |
1202 int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages) | |
1203 * vm_page_size()) + framesize_in_bytes; | |
1204 // The very lower end of the stack | |
1205 address stack_limit = thread->stack_base() - thread->stack_size(); | |
1206 return (sp > (stack_limit + reserved_area)); | |
1207 } | |
1208 | |
1209 size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size, | |
1210 uint min_pages) | |
1211 { | |
1212 assert(min_pages > 0, "sanity"); | |
1213 if (UseLargePages) { | |
1214 const size_t max_page_size = region_max_size / min_pages; | |
1215 | |
1216 for (unsigned int i = 0; _page_sizes[i] != 0; ++i) { | |
1217 const size_t sz = _page_sizes[i]; | |
1218 const size_t mask = sz - 1; | |
1219 if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) { | |
1220 // The largest page size with no fragmentation. | |
1221 return sz; | |
1222 } | |
1223 | |
1224 if (sz <= max_page_size) { | |
1225 // The largest page size that satisfies the min_pages requirement. | |
1226 return sz; | |
1227 } | |
1228 } | |
1229 } | |
1230 | |
1231 return vm_page_size(); | |
1232 } | |
1233 | |
1234 #ifndef PRODUCT | |
3859 | 1235 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count) |
1236 { | |
1237 if (TracePageSizes) { | |
1238 tty->print("%s: ", str); | |
1239 for (int i = 0; i < count; ++i) { | |
1240 tty->print(" " SIZE_FORMAT, page_sizes[i]); | |
1241 } | |
1242 tty->cr(); | |
1243 } | |
1244 } | |
1245 | |
0 | 1246 void os::trace_page_sizes(const char* str, const size_t region_min_size, |
1247 const size_t region_max_size, const size_t page_size, | |
1248 const char* base, const size_t size) | |
1249 { | |
1250 if (TracePageSizes) { | |
1251 tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT | |
1252 " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT | |
1253 " size=" SIZE_FORMAT, | |
1254 str, region_min_size, region_max_size, | |
1255 page_size, base, size); | |
1256 } | |
1257 } | |
1258 #endif // #ifndef PRODUCT | |
1259 | |
1260 // This is the working definition of a server class machine: | |
1261 // >= 2 physical CPU's and >=2GB of memory, with some fuzz | |
1262 // because the graphics memory (?) sometimes masks physical memory. | |
1263 // If you want to change the definition of a server class machine | |
1264 // on some OS or platform, e.g., >=4GB on Windohs platforms, | |
1265 // then you'll have to parameterize this method based on that state, | |
1266 // as was done for logical processors here, or replicate and | |
1267 // specialize this method for each platform. (Or fix os to have | |
1268 // some inheritance structure and use subclassing. Sigh.) | |
1269 // If you want some platform to always or never behave as a server | |
1270 // class machine, change the setting of AlwaysActAsServerClassMachine | |
1271 // and NeverActAsServerClassMachine in globals*.hpp. | |
1272 bool os::is_server_class_machine() { | |
1273 // First check for the early returns | |
1274 if (NeverActAsServerClassMachine) { | |
1275 return false; | |
1276 } | |
1277 if (AlwaysActAsServerClassMachine) { | |
1278 return true; | |
1279 } | |
1280 // Then actually look at the machine | |
1281 bool result = false; | |
1282 const unsigned int server_processors = 2; | |
1283 const julong server_memory = 2UL * G; | |
1284 // We seem not to get our full complement of memory. | |
1285 // We allow some part (1/8?) of the memory to be "missing", | |
1286 // based on the sizes of DIMMs, and maybe graphics cards. | |
1287 const julong missing_memory = 256UL * M; | |
1288 | |
1289 /* Is this a server class machine? */ | |
1290 if ((os::active_processor_count() >= (int)server_processors) && | |
1291 (os::physical_memory() >= (server_memory - missing_memory))) { | |
1292 const unsigned int logical_processors = | |
1293 VM_Version::logical_processors_per_package(); | |
1294 if (logical_processors > 1) { | |
1295 const unsigned int physical_packages = | |
1296 os::active_processor_count() / logical_processors; | |
1297 if (physical_packages > server_processors) { | |
1298 result = true; | |
1299 } | |
1300 } else { | |
1301 result = true; | |
1302 } | |
1303 } | |
1304 return result; | |
1305 } | |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1306 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1307 // Read file line by line, if line is longer than bsize, |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1308 // skip rest of line. |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1309 int os::get_line_chars(int fd, char* buf, const size_t bsize){ |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1310 size_t sz, i = 0; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1311 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1312 // read until EOF, EOL or buf is full |
3832 | 1313 while ((sz = (int) read(fd, &buf[i], 1)) == 1 && i < (bsize-2) && buf[i] != '\n') { |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1314 ++i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1315 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1316 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1317 if (buf[i] == '\n') { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1318 // EOL reached so ignore EOL character and return |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1319 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1320 buf[i] = 0; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1321 return (int) i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1322 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1323 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1324 buf[i+1] = 0; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1325 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1326 if (sz != 1) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1327 // EOF reached. if we read chars before EOF return them and |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1328 // return EOF on next call otherwise return EOF |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1329 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1330 return (i == 0) ? -1 : (int) i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1331 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1332 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1333 // line is longer than size of buf, skip to EOL |
3832 | 1334 char ch; |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1335 while (read(fd, &ch, 1) == 1 && ch != '\n') { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1336 // Do nothing |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1337 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1338 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1339 // return initial part of line that fits in buf. |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1340 // If we reached EOF, it will be returned on next call. |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1341 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1342 return (int) i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1343 } |