Mercurial > hg > truffle
annotate src/share/vm/runtime/os.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | 716c64bda5ba |
children | e522a00b91aa 6cb0d32b828b e4f764ddb06a |
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 MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller); | |
604 | |
0 | 605 return memblock; |
606 } | |
607 | |
608 | |
6197 | 609 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) { |
0 | 610 #ifndef ASSERT |
2250 | 611 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); |
612 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); | |
6197 | 613 void* ptr = ::realloc(memblock, size); |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
614 if (ptr != NULL) { |
6197 | 615 MemTracker::record_realloc((address)memblock, (address)ptr, size, memflags, |
616 caller == 0 ? CALLER_PC : caller); | |
617 } | |
618 return ptr; | |
0 | 619 #else |
620 if (memblock == NULL) { | |
6197 | 621 return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller)); |
0 | 622 } |
623 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | |
2250 | 624 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock); |
0 | 625 breakpoint(); |
626 } | |
627 verify_block(memblock); | |
628 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | |
629 if (size == 0) return NULL; | |
630 // always move the block | |
6197 | 631 void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller); |
2250 | 632 if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr); |
0 | 633 // Copy to new memory if malloc didn't fail |
634 if ( ptr != NULL ) { | |
635 memcpy(ptr, memblock, MIN2(size, get_size(memblock))); | |
636 if (paranoid) verify_block(ptr); | |
637 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) { | |
2250 | 638 tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr); |
0 | 639 breakpoint(); |
640 } | |
641 free(memblock); | |
642 } | |
643 return ptr; | |
644 #endif | |
645 } | |
646 | |
647 | |
6197 | 648 void os::free(void *memblock, MEMFLAGS memflags) { |
2250 | 649 NOT_PRODUCT(inc_stat_counter(&num_frees, 1)); |
0 | 650 #ifdef ASSERT |
651 if (memblock == NULL) return; | |
652 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) { | |
2250 | 653 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock); |
0 | 654 breakpoint(); |
655 } | |
656 verify_block(memblock); | |
657 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); | |
658 // Added by detlefs. | |
659 if (MallocCushion) { | |
660 u_char* ptr = (u_char*)memblock - space_before; | |
661 for (u_char* p = ptr; p < ptr + MallocCushion; p++) { | |
662 guarantee(*p == badResourceValue, | |
663 "Thing freed should be malloc result."); | |
664 *p = (u_char)freeBlockPad; | |
665 } | |
666 size_t size = get_size(memblock); | |
2250 | 667 inc_stat_counter(&free_bytes, size); |
0 | 668 u_char* end = ptr + space_before + size; |
669 for (u_char* q = end; q < end + MallocCushion; q++) { | |
670 guarantee(*q == badResourceValue, | |
671 "Thing freed should be malloc result."); | |
672 *q = (u_char)freeBlockPad; | |
673 } | |
2250 | 674 if (PrintMalloc && tty != NULL) |
2333
f767174aac14
7021653: Parfait issue in hotspot/src/share/vm/oops/methodDataOops.hpp
coleenp
parents:
2250
diff
changeset
|
675 fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock); |
2250 | 676 } else if (PrintMalloc && tty != NULL) { |
677 // 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
|
678 fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock); |
0 | 679 } |
680 #endif | |
6197 | 681 MemTracker::record_free((address)memblock, memflags); |
682 | |
0 | 683 ::free((char*)memblock - space_before); |
684 } | |
685 | |
686 void os::init_random(long initval) { | |
687 _rand_seed = initval; | |
688 } | |
689 | |
690 | |
691 long os::random() { | |
692 /* standard, well-known linear congruential random generator with | |
693 * next_rand = (16807*seed) mod (2**31-1) | |
694 * see | |
695 * (1) "Random Number Generators: Good Ones Are Hard to Find", | |
696 * S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988), | |
697 * (2) "Two Fast Implementations of the 'Minimal Standard' Random | |
698 * Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), pp. 87-88. | |
699 */ | |
700 const long a = 16807; | |
701 const unsigned long m = 2147483647; | |
702 const long q = m / a; assert(q == 127773, "weird math"); | |
703 const long r = m % a; assert(r == 2836, "weird math"); | |
704 | |
705 // compute az=2^31p+q | |
706 unsigned long lo = a * (long)(_rand_seed & 0xFFFF); | |
707 unsigned long hi = a * (long)((unsigned long)_rand_seed >> 16); | |
708 lo += (hi & 0x7FFF) << 16; | |
709 | |
710 // if q overflowed, ignore the overflow and increment q | |
711 if (lo > m) { | |
712 lo &= m; | |
713 ++lo; | |
714 } | |
715 lo += hi >> 15; | |
716 | |
717 // if (p+q) overflowed, ignore the overflow and increment (p+q) | |
718 if (lo > m) { | |
719 lo &= m; | |
720 ++lo; | |
721 } | |
722 return (_rand_seed = lo); | |
723 } | |
724 | |
725 // The INITIALIZED state is distinguished from the SUSPENDED state because the | |
726 // conditions in which a thread is first started are different from those in which | |
727 // a suspension is resumed. These differences make it hard for us to apply the | |
728 // tougher checks when starting threads that we want to do when resuming them. | |
729 // However, when start_thread is called as a result of Thread.start, on a Java | |
730 // thread, the operation is synchronized on the Java Thread object. So there | |
731 // cannot be a race to start the thread and hence for the thread to exit while | |
732 // we are working on it. Non-Java threads that start Java threads either have | |
733 // to do so in a context in which races are impossible, or should do appropriate | |
734 // locking. | |
735 | |
736 void os::start_thread(Thread* thread) { | |
737 // guard suspend/resume | |
738 MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag); | |
739 OSThread* osthread = thread->osthread(); | |
740 osthread->set_state(RUNNABLE); | |
741 pd_start_thread(thread); | |
742 } | |
743 | |
744 //--------------------------------------------------------------------------- | |
745 // Helper functions for fatal error handler | |
746 | |
747 void os::print_hex_dump(outputStream* st, address start, address end, int unitsize) { | |
748 assert(unitsize == 1 || unitsize == 2 || unitsize == 4 || unitsize == 8, "just checking"); | |
749 | |
750 int cols = 0; | |
751 int cols_per_line = 0; | |
752 switch (unitsize) { | |
753 case 1: cols_per_line = 16; break; | |
754 case 2: cols_per_line = 8; break; | |
755 case 4: cols_per_line = 4; break; | |
756 case 8: cols_per_line = 2; break; | |
757 default: return; | |
758 } | |
759 | |
760 address p = start; | |
761 st->print(PTR_FORMAT ": ", start); | |
762 while (p < end) { | |
763 switch (unitsize) { | |
764 case 1: st->print("%02x", *(u1*)p); break; | |
765 case 2: st->print("%04x", *(u2*)p); break; | |
766 case 4: st->print("%08x", *(u4*)p); break; | |
767 case 8: st->print("%016" FORMAT64_MODIFIER "x", *(u8*)p); break; | |
768 } | |
769 p += unitsize; | |
770 cols++; | |
771 if (cols >= cols_per_line && p < end) { | |
772 cols = 0; | |
773 st->cr(); | |
774 st->print(PTR_FORMAT ": ", p); | |
775 } else { | |
776 st->print(" "); | |
777 } | |
778 } | |
779 st->cr(); | |
780 } | |
781 | |
782 void os::print_environment_variables(outputStream* st, const char** env_list, | |
783 char* buffer, int len) { | |
784 if (env_list) { | |
785 st->print_cr("Environment Variables:"); | |
786 | |
787 for (int i = 0; env_list[i] != NULL; i++) { | |
788 if (getenv(env_list[i], buffer, len)) { | |
789 st->print(env_list[i]); | |
790 st->print("="); | |
791 st->print_cr(buffer); | |
792 } | |
793 } | |
794 } | |
795 } | |
796 | |
797 void os::print_cpu_info(outputStream* st) { | |
798 // cpu | |
799 st->print("CPU:"); | |
800 st->print("total %d", os::processor_count()); | |
801 // It's not safe to query number of active processors after crash | |
802 // st->print("(active %d)", os::active_processor_count()); | |
803 st->print(" %s", VM_Version::cpu_features()); | |
804 st->cr(); | |
3800
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
2469
diff
changeset
|
805 pd_print_cpu_info(st); |
0 | 806 } |
807 | |
808 void os::print_date_and_time(outputStream *st) { | |
809 time_t tloc; | |
810 (void)time(&tloc); | |
811 st->print("time: %s", ctime(&tloc)); // ctime adds newline. | |
812 | |
813 double t = os::elapsedTime(); | |
814 // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in | |
815 // Linux. Must be a bug in glibc ? Workaround is to round "t" to int | |
816 // before printf. We lost some precision, but who cares? | |
817 st->print_cr("elapsed time: %d seconds", (int)t); | |
818 } | |
819 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
820 // moved from debug.cpp (used to be find()) but still called from there |
1907 | 821 // The verbose parameter is only set by the debug code in one case |
822 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
|
823 address addr = (address)x; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
824 CodeBlob* b = CodeCache::find_blob_unsafe(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
825 if (b != NULL) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
826 if (b->is_buffer_blob()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
827 // the interpreter is generated into a buffer blob |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
828 InterpreterCodelet* i = Interpreter::codelet_containing(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
829 if (i != NULL) { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
830 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
|
831 i->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
832 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
833 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
834 if (Interpreter::contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
835 st->print_cr(INTPTR_FORMAT " is pointing into interpreter code" |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
836 " (not bytecode specific)", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
837 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
838 } |
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 (AdapterHandlerLibrary::contains(b)) { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
841 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
|
842 AdapterHandlerLibrary::print_handler_on(st, b); |
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 // the stubroutines are generated into a buffer blob |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
845 StubCodeDesc* d = StubCodeDesc::desc_for(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
846 if (d != NULL) { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
847 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
|
848 d->print_on(st); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
849 st->cr(); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
850 return; |
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 if (StubRoutines::contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
853 st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) " |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
854 "stub routine", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
855 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
856 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
857 // the InlineCacheBuffer is using stubs generated into a buffer blob |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
858 if (InlineCacheBuffer::contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
859 st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
860 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
861 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
862 VtableStub* v = VtableStubs::stub_containing(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
863 if (v != NULL) { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
864 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
|
865 v->print_on(st); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
866 st->cr(); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
867 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
868 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
869 } |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
870 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
|
871 if (nm != NULL) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
872 ResourceMark rm; |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
873 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
|
874 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
|
875 if (verbose) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
876 st->print(" for "); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
877 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
|
878 } |
6816
87ac5c0a404d
8000228: Missing call to cr() when printing entry_point in nmethod, in os::print_location
stefank
parents:
6814
diff
changeset
|
879 st->cr(); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
880 nm->print_nmethod(verbose); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
881 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
882 } |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6197
diff
changeset
|
883 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
|
884 b->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
885 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
886 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
887 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
888 if (Universe::heap()->is_in(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
889 HeapWord* p = Universe::heap()->block_start(addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
890 bool print = false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
891 // 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
|
892 // See if we were just given an oop directly |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
893 if (p != NULL && Universe::heap()->block_is_obj(p)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
894 print = true; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
895 } else if (p == NULL && ((oopDesc*)addr)->is_oop()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
896 p = (HeapWord*) addr; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
897 print = true; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
898 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
899 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
|
900 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
|
901 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
|
902 } else { |
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 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
|
904 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
905 oop(p)->print_on(st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
906 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
907 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
908 } else { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
909 if (Universe::heap()->is_in_reserved(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
910 st->print_cr(INTPTR_FORMAT " is an unallocated location " |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
911 "in the heap", addr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
912 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
913 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
914 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
915 if (JNIHandles::is_global_handle((jobject) addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
916 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
|
917 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
918 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
919 if (JNIHandles::is_weak_global_handle((jobject) addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
920 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
|
921 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
922 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
923 #ifndef PRODUCT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
924 // we don't keep the block list in product mode |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
925 if (JNIHandleBlock::any_contains((jobject) addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
926 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
|
927 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
928 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
929 #endif |
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 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
932 // Check for privilege stack |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
933 if (thread->privileged_stack_top() != NULL && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
934 thread->privileged_stack_top()->contains(addr)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
935 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
|
936 "for thread: " INTPTR_FORMAT, addr, thread); |
1907 | 937 if (verbose) thread->print_on(st); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
938 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
939 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
940 // 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
|
941 if (addr == (address)thread) { |
1907 | 942 if (verbose) { |
943 thread->print_on(st); | |
944 } else { | |
945 st->print_cr(INTPTR_FORMAT " is a thread", addr); | |
946 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
947 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
948 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
949 // 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
|
950 // and print thread info |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
951 if (thread->stack_base() >= addr && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
952 addr > (thread->stack_base() - thread->stack_size())) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
953 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
|
954 INTPTR_FORMAT, addr, thread); |
1907 | 955 if (verbose) thread->print_on(st); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
956 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
957 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
958 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
959 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
960 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
961 #ifndef PRODUCT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
962 // Check if in metaspace. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
963 if (ClassLoaderDataGraph::contains((address)addr)) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
964 // 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
|
965 st->print_cr(INTPTR_FORMAT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
966 " is pointing into metadata", addr); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
967 return; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
968 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
969 #endif |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
970 |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
971 // Try an OS specific find |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
972 if (os::find(addr, st)) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
973 return; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
974 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
975 |
1907 | 976 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
|
977 } |
0 | 978 |
979 // Looks like all platforms except IA64 can use the same function to check | |
980 // if C stack is walkable beyond current frame. The check for fp() is not | |
981 // necessary on Sparc, but it's harmless. | |
982 bool os::is_first_C_frame(frame* fr) { | |
983 #ifdef IA64 | |
984 // In order to walk native frames on Itanium, we need to access the unwind | |
985 // table, which is inside ELF. We don't want to parse ELF after fatal error, | |
986 // so return true for IA64. If we need to support C stack walking on IA64, | |
987 // this function needs to be moved to CPU specific files, as fp() on IA64 | |
988 // is register stack, which grows towards higher memory address. | |
989 return true; | |
990 #endif | |
991 | |
992 // Load up sp, fp, sender sp and sender fp, check for reasonable values. | |
993 // Check usp first, because if that's bad the other accessors may fault | |
994 // on some architectures. Ditto ufp second, etc. | |
995 uintptr_t fp_align_mask = (uintptr_t)(sizeof(address)-1); | |
996 // sp on amd can be 32 bit aligned. | |
997 uintptr_t sp_align_mask = (uintptr_t)(sizeof(int)-1); | |
998 | |
999 uintptr_t usp = (uintptr_t)fr->sp(); | |
1000 if ((usp & sp_align_mask) != 0) return true; | |
1001 | |
1002 uintptr_t ufp = (uintptr_t)fr->fp(); | |
1003 if ((ufp & fp_align_mask) != 0) return true; | |
1004 | |
1005 uintptr_t old_sp = (uintptr_t)fr->sender_sp(); | |
1006 if ((old_sp & sp_align_mask) != 0) return true; | |
1007 if (old_sp == 0 || old_sp == (uintptr_t)-1) return true; | |
1008 | |
1009 uintptr_t old_fp = (uintptr_t)fr->link(); | |
1010 if ((old_fp & fp_align_mask) != 0) return true; | |
1011 if (old_fp == 0 || old_fp == (uintptr_t)-1 || old_fp == ufp) return true; | |
1012 | |
1013 // stack grows downwards; if old_fp is below current fp or if the stack | |
1014 // frame is too large, either the stack is corrupted or fp is not saved | |
1015 // on stack (i.e. on x86, ebp may be used as general register). The stack | |
1016 // is not walkable beyond current frame. | |
1017 if (old_fp < ufp) return true; | |
1018 if (old_fp - ufp > 64 * K) return true; | |
1019 | |
1020 return false; | |
1021 } | |
1022 | |
1023 #ifdef ASSERT | |
1024 extern "C" void test_random() { | |
1025 const double m = 2147483647; | |
1026 double mean = 0.0, variance = 0.0, t; | |
1027 long reps = 10000; | |
1028 unsigned long seed = 1; | |
1029 | |
1030 tty->print_cr("seed %ld for %ld repeats...", seed, reps); | |
1031 os::init_random(seed); | |
1032 long num; | |
1033 for (int k = 0; k < reps; k++) { | |
1034 num = os::random(); | |
1035 double u = (double)num / m; | |
1036 assert(u >= 0.0 && u <= 1.0, "bad random number!"); | |
1037 | |
1038 // calculate mean and variance of the random sequence | |
1039 mean += u; | |
1040 variance += (u*u); | |
1041 } | |
1042 mean /= reps; | |
1043 variance /= (reps - 1); | |
1044 | |
1045 assert(num == 1043618065, "bad seed"); | |
1046 tty->print_cr("mean of the 1st 10000 numbers: %f", mean); | |
1047 tty->print_cr("variance of the 1st 10000 numbers: %f", variance); | |
1048 const double eps = 0.0001; | |
1049 t = fabsd(mean - 0.5018); | |
1050 assert(t < eps, "bad mean"); | |
1051 t = (variance - 0.3355) < 0.0 ? -(variance - 0.3355) : variance - 0.3355; | |
1052 assert(t < eps, "bad variance"); | |
1053 } | |
1054 #endif | |
1055 | |
1056 | |
1057 // Set up the boot classpath. | |
1058 | |
1059 char* os::format_boot_path(const char* format_string, | |
1060 const char* home, | |
1061 int home_len, | |
1062 char fileSep, | |
1063 char pathSep) { | |
1064 assert((fileSep == '/' && pathSep == ':') || | |
1065 (fileSep == '\\' && pathSep == ';'), "unexpected seperator chars"); | |
1066 | |
1067 // Scan the format string to determine the length of the actual | |
1068 // boot classpath, and handle platform dependencies as well. | |
1069 int formatted_path_len = 0; | |
1070 const char* p; | |
1071 for (p = format_string; *p != 0; ++p) { | |
1072 if (*p == '%') formatted_path_len += home_len - 1; | |
1073 ++formatted_path_len; | |
1074 } | |
1075 | |
6197 | 1076 char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1, mtInternal); |
0 | 1077 if (formatted_path == NULL) { |
1078 return NULL; | |
1079 } | |
1080 | |
1081 // Create boot classpath from format, substituting separator chars and | |
1082 // java home directory. | |
1083 char* q = formatted_path; | |
1084 for (p = format_string; *p != 0; ++p) { | |
1085 switch (*p) { | |
1086 case '%': | |
1087 strcpy(q, home); | |
1088 q += home_len; | |
1089 break; | |
1090 case '/': | |
1091 *q++ = fileSep; | |
1092 break; | |
1093 case ':': | |
1094 *q++ = pathSep; | |
1095 break; | |
1096 default: | |
1097 *q++ = *p; | |
1098 } | |
1099 } | |
1100 *q = '\0'; | |
1101 | |
1102 assert((q - formatted_path) == formatted_path_len, "formatted_path size botched"); | |
1103 return formatted_path; | |
1104 } | |
1105 | |
1106 | |
1107 bool os::set_boot_path(char fileSep, char pathSep) { | |
1108 const char* home = Arguments::get_java_home(); | |
1109 int home_len = (int)strlen(home); | |
1110 | |
1111 static const char* meta_index_dir_format = "%/lib/"; | |
1112 static const char* meta_index_format = "%/lib/meta-index"; | |
1113 char* meta_index = format_boot_path(meta_index_format, home, home_len, fileSep, pathSep); | |
1114 if (meta_index == NULL) return false; | |
1115 char* meta_index_dir = format_boot_path(meta_index_dir_format, home, home_len, fileSep, pathSep); | |
1116 if (meta_index_dir == NULL) return false; | |
1117 Arguments::set_meta_index_path(meta_index, meta_index_dir); | |
1118 | |
1119 // Any modification to the JAR-file list, for the boot classpath must be | |
1120 // aligned with install/install/make/common/Pack.gmk. Note: boot class | |
1121 // path class JARs, are stripped for StackMapTable to reduce download size. | |
1122 static const char classpath_format[] = | |
1123 "%/lib/resources.jar:" | |
1124 "%/lib/rt.jar:" | |
1125 "%/lib/sunrsasign.jar:" | |
1126 "%/lib/jsse.jar:" | |
1127 "%/lib/jce.jar:" | |
1128 "%/lib/charsets.jar:" | |
4800
94ec88ca68e2
7115199: Add event tracing hooks and Java Flight Recorder infrastructure
phh
parents:
4749
diff
changeset
|
1129 "%/lib/jfr.jar:" |
4006 | 1130 #ifdef __APPLE__ |
1131 "%/lib/JObjC.jar:" | |
1132 #endif | |
0 | 1133 "%/classes"; |
1134 char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep); | |
1135 if (sysclasspath == NULL) return false; | |
1136 Arguments::set_sysclasspath(sysclasspath); | |
1137 | |
1138 return true; | |
1139 } | |
1140 | |
691 | 1141 /* |
1142 * Splits a path, based on its separator, the number of | |
1143 * elements is returned back in n. | |
1144 * It is the callers responsibility to: | |
1145 * a> check the value of n, and n may be 0. | |
1146 * b> ignore any empty path elements | |
1147 * c> free up the data. | |
1148 */ | |
1149 char** os::split_path(const char* path, int* n) { | |
1150 *n = 0; | |
1151 if (path == NULL || strlen(path) == 0) { | |
1152 return NULL; | |
1153 } | |
1154 const char psepchar = *os::path_separator(); | |
6197 | 1155 char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal); |
691 | 1156 if (inpath == NULL) { |
1157 return NULL; | |
1158 } | |
1159 strncpy(inpath, path, strlen(path)); | |
1160 int count = 1; | |
1161 char* p = strchr(inpath, psepchar); | |
1162 // Get a count of elements to allocate memory | |
1163 while (p != NULL) { | |
1164 count++; | |
1165 p++; | |
1166 p = strchr(p, psepchar); | |
1167 } | |
6197 | 1168 char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal); |
691 | 1169 if (opath == NULL) { |
1170 return NULL; | |
1171 } | |
1172 | |
1173 // do the actual splitting | |
1174 p = inpath; | |
1175 for (int i = 0 ; i < count ; i++) { | |
1176 size_t len = strcspn(p, os::path_separator()); | |
1177 if (len > JVM_MAXPATHLEN) { | |
1178 return NULL; | |
1179 } | |
1180 // allocate the string and add terminator storage | |
6197 | 1181 char* s = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); |
691 | 1182 if (s == NULL) { |
1183 return NULL; | |
1184 } | |
1185 strncpy(s, p, len); | |
1186 s[len] = '\0'; | |
1187 opath[i] = s; | |
1188 p += len + 1; | |
1189 } | |
6197 | 1190 FREE_C_HEAP_ARRAY(char, inpath, mtInternal); |
691 | 1191 *n = count; |
1192 return opath; | |
1193 } | |
1194 | |
0 | 1195 void os::set_memory_serialize_page(address page) { |
1196 int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); | |
1197 _mem_serialize_page = (volatile int32_t *)page; | |
1198 // We initialize the serialization page shift count here | |
1199 // We assume a cache line size of 64 bytes | |
1200 assert(SerializePageShiftCount == count, | |
1201 "thread size changed, fix SerializePageShiftCount constant"); | |
1202 set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t))); | |
1203 } | |
1204 | |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1205 static volatile intptr_t SerializePageLock = 0; |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1206 |
0 | 1207 // This method is called from signal handler when SIGSEGV occurs while the current |
1208 // thread tries to store to the "read-only" memory serialize page during state | |
1209 // transition. | |
1210 void os::block_on_serialize_page_trap() { | |
1211 if (TraceSafepoint) { | |
1212 tty->print_cr("Block until the serialize page permission restored"); | |
1213 } | |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1214 // When VMThread is holding the SerializePageLock during modifying the |
0 | 1215 // access permission of the memory serialize page, the following call |
1216 // will block until the permission of that page is restored to rw. | |
1217 // Generally, it is unsafe to manipulate locks in signal handlers, but in | |
1218 // 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
|
1219 // it can occur. |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1220 Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page"); |
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1221 Thread::muxRelease(&SerializePageLock); |
0 | 1222 } |
1223 | |
1224 // Serialize all thread state variables | |
1225 void os::serialize_thread_states() { | |
1226 // On some platforms such as Solaris & Linux, the time duration of the page | |
1227 // permission restoration is observed to be much longer than expected due to | |
1228 // 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
|
1229 // 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
|
1230 // 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
|
1231 Thread::muxAcquire(&SerializePageLock, "serialize_thread_states"); |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
1232 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
|
1233 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
|
1234 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
|
1235 os::vm_page_size(), MEM_PROT_RW); |
55
2a8eb116ebbe
6610420: Debug VM crashes during monitor lock rank checking
xlu
parents:
0
diff
changeset
|
1236 Thread::muxRelease(&SerializePageLock); |
0 | 1237 } |
1238 | |
1239 // Returns true if the current stack pointer is above the stack shadow | |
1240 // pages, false otherwise. | |
1241 | |
1242 bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) { | |
1243 assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check"); | |
1244 address sp = current_stack_pointer(); | |
1245 // Check if we have StackShadowPages above the yellow zone. This parameter | |
605 | 1246 // is dependent on the depth of the maximum VM call stack possible from |
0 | 1247 // the handler for stack overflow. 'instanceof' in the stack overflow |
1248 // handler or a println uses at least 8k stack of VM and native code | |
1249 // respectively. | |
1250 const int framesize_in_bytes = | |
1251 Interpreter::size_top_interpreter_activation(method()) * wordSize; | |
1252 int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages) | |
1253 * vm_page_size()) + framesize_in_bytes; | |
1254 // The very lower end of the stack | |
1255 address stack_limit = thread->stack_base() - thread->stack_size(); | |
1256 return (sp > (stack_limit + reserved_area)); | |
1257 } | |
1258 | |
1259 size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size, | |
1260 uint min_pages) | |
1261 { | |
1262 assert(min_pages > 0, "sanity"); | |
1263 if (UseLargePages) { | |
1264 const size_t max_page_size = region_max_size / min_pages; | |
1265 | |
1266 for (unsigned int i = 0; _page_sizes[i] != 0; ++i) { | |
1267 const size_t sz = _page_sizes[i]; | |
1268 const size_t mask = sz - 1; | |
1269 if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) { | |
1270 // The largest page size with no fragmentation. | |
1271 return sz; | |
1272 } | |
1273 | |
1274 if (sz <= max_page_size) { | |
1275 // The largest page size that satisfies the min_pages requirement. | |
1276 return sz; | |
1277 } | |
1278 } | |
1279 } | |
1280 | |
1281 return vm_page_size(); | |
1282 } | |
1283 | |
1284 #ifndef PRODUCT | |
3859 | 1285 void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count) |
1286 { | |
1287 if (TracePageSizes) { | |
1288 tty->print("%s: ", str); | |
1289 for (int i = 0; i < count; ++i) { | |
1290 tty->print(" " SIZE_FORMAT, page_sizes[i]); | |
1291 } | |
1292 tty->cr(); | |
1293 } | |
1294 } | |
1295 | |
0 | 1296 void os::trace_page_sizes(const char* str, const size_t region_min_size, |
1297 const size_t region_max_size, const size_t page_size, | |
1298 const char* base, const size_t size) | |
1299 { | |
1300 if (TracePageSizes) { | |
1301 tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT | |
1302 " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT | |
1303 " size=" SIZE_FORMAT, | |
1304 str, region_min_size, region_max_size, | |
1305 page_size, base, size); | |
1306 } | |
1307 } | |
1308 #endif // #ifndef PRODUCT | |
1309 | |
1310 // This is the working definition of a server class machine: | |
1311 // >= 2 physical CPU's and >=2GB of memory, with some fuzz | |
1312 // because the graphics memory (?) sometimes masks physical memory. | |
1313 // If you want to change the definition of a server class machine | |
1314 // on some OS or platform, e.g., >=4GB on Windohs platforms, | |
1315 // then you'll have to parameterize this method based on that state, | |
1316 // as was done for logical processors here, or replicate and | |
1317 // specialize this method for each platform. (Or fix os to have | |
1318 // some inheritance structure and use subclassing. Sigh.) | |
1319 // If you want some platform to always or never behave as a server | |
1320 // class machine, change the setting of AlwaysActAsServerClassMachine | |
1321 // and NeverActAsServerClassMachine in globals*.hpp. | |
1322 bool os::is_server_class_machine() { | |
1323 // First check for the early returns | |
1324 if (NeverActAsServerClassMachine) { | |
1325 return false; | |
1326 } | |
1327 if (AlwaysActAsServerClassMachine) { | |
1328 return true; | |
1329 } | |
1330 // Then actually look at the machine | |
1331 bool result = false; | |
1332 const unsigned int server_processors = 2; | |
1333 const julong server_memory = 2UL * G; | |
1334 // We seem not to get our full complement of memory. | |
1335 // We allow some part (1/8?) of the memory to be "missing", | |
1336 // based on the sizes of DIMMs, and maybe graphics cards. | |
1337 const julong missing_memory = 256UL * M; | |
1338 | |
1339 /* Is this a server class machine? */ | |
1340 if ((os::active_processor_count() >= (int)server_processors) && | |
1341 (os::physical_memory() >= (server_memory - missing_memory))) { | |
1342 const unsigned int logical_processors = | |
1343 VM_Version::logical_processors_per_package(); | |
1344 if (logical_processors > 1) { | |
1345 const unsigned int physical_packages = | |
1346 os::active_processor_count() / logical_processors; | |
1347 if (physical_packages > server_processors) { | |
1348 result = true; | |
1349 } | |
1350 } else { | |
1351 result = true; | |
1352 } | |
1353 } | |
1354 return result; | |
1355 } | |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1356 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1357 // 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
|
1358 // skip rest of line. |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1359 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
|
1360 size_t sz, i = 0; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1361 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1362 // read until EOF, EOL or buf is full |
3832 | 1363 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
|
1364 ++i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1365 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1366 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1367 if (buf[i] == '\n') { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1368 // 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
|
1369 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1370 buf[i] = 0; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1371 return (int) i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1372 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1373 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1374 buf[i+1] = 0; |
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 if (sz != 1) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1377 // 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
|
1378 // 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
|
1379 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1380 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
|
1381 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1382 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1383 // line is longer than size of buf, skip to EOL |
3832 | 1384 char ch; |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1385 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
|
1386 // Do nothing |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1387 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1388 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1389 // 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
|
1390 // 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
|
1391 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1392 return (int) i; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2387
diff
changeset
|
1393 } |
6197 | 1394 |
1395 bool os::create_stack_guard_pages(char* addr, size_t bytes) { | |
1396 return os::pd_create_stack_guard_pages(addr, bytes); | |
1397 } | |
1398 | |
1399 | |
1400 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { | |
1401 char* result = pd_reserve_memory(bytes, addr, alignment_hint); | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1402 if (result != NULL) { |
6197 | 1403 MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); |
1404 } | |
1405 | |
1406 return result; | |
1407 } | |
1408 char* os::attempt_reserve_memory_at(size_t bytes, char* addr) { | |
1409 char* result = pd_attempt_reserve_memory_at(bytes, addr); | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1410 if (result != NULL) { |
6197 | 1411 MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); |
1412 } | |
1413 return result; | |
1414 } | |
1415 | |
1416 void os::split_reserved_memory(char *base, size_t size, | |
1417 size_t split, bool realloc) { | |
1418 pd_split_reserved_memory(base, size, split, realloc); | |
1419 } | |
1420 | |
1421 bool os::commit_memory(char* addr, size_t bytes, bool executable) { | |
1422 bool res = pd_commit_memory(addr, bytes, executable); | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1423 if (res) { |
6197 | 1424 MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC); |
1425 } | |
1426 return res; | |
1427 } | |
1428 | |
1429 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, | |
1430 bool executable) { | |
1431 bool res = os::pd_commit_memory(addr, size, alignment_hint, executable); | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1432 if (res) { |
6197 | 1433 MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC); |
1434 } | |
1435 return res; | |
1436 } | |
1437 | |
1438 bool os::uncommit_memory(char* addr, size_t bytes) { | |
1439 bool res = pd_uncommit_memory(addr, bytes); | |
1440 if (res) { | |
1441 MemTracker::record_virtual_memory_uncommit((address)addr, bytes); | |
1442 } | |
1443 return res; | |
1444 } | |
1445 | |
1446 bool os::release_memory(char* addr, size_t bytes) { | |
1447 bool res = pd_release_memory(addr, bytes); | |
1448 if (res) { | |
1449 MemTracker::record_virtual_memory_release((address)addr, bytes); | |
1450 } | |
1451 return res; | |
1452 } | |
1453 | |
1454 | |
1455 char* os::map_memory(int fd, const char* file_name, size_t file_offset, | |
1456 char *addr, size_t bytes, bool read_only, | |
1457 bool allow_exec) { | |
1458 char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec); | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1459 if (result != NULL) { |
6197 | 1460 MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1461 MemTracker::record_virtual_memory_commit((address)result, bytes, CALLER_PC); |
6197 | 1462 } |
1463 return result; | |
1464 } | |
1465 | |
1466 char* os::remap_memory(int fd, const char* file_name, size_t file_offset, | |
1467 char *addr, size_t bytes, bool read_only, | |
1468 bool allow_exec) { | |
1469 return pd_remap_memory(fd, file_name, file_offset, addr, bytes, | |
1470 read_only, allow_exec); | |
1471 } | |
1472 | |
1473 bool os::unmap_memory(char *addr, size_t bytes) { | |
1474 bool result = pd_unmap_memory(addr, bytes); | |
1475 if (result) { | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6816
diff
changeset
|
1476 MemTracker::record_virtual_memory_uncommit((address)addr, bytes); |
6197 | 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 |