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