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