Mercurial > hg > truffle
diff src/share/vm/runtime/sharedRuntime.cpp @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | 3e9a960f0da1 |
children | 954c9df6ac79 |
line wrap: on
line diff
--- a/src/share/vm/runtime/sharedRuntime.cpp Tue Apr 01 14:09:03 2014 +0200 +++ b/src/share/vm/runtime/sharedRuntime.cpp Tue Apr 01 13:57:07 2014 +0200 @@ -127,6 +127,14 @@ #include <math.h> +#ifndef USDT2 +HS_DTRACE_PROBE_DECL4(hotspot, object__alloc, Thread*, char*, int, size_t); +HS_DTRACE_PROBE_DECL7(hotspot, method__entry, int, + char*, int, char*, int, char*, int); +HS_DTRACE_PROBE_DECL7(hotspot, method__return, int, + char*, int, char*, int, char*, int); +#endif /* !USDT2 */ + // Implementation of SharedRuntime #ifndef PRODUCT @@ -400,7 +408,7 @@ #endif -#if defined(__SOFTFP__) || defined(PPC32) +#if defined(__SOFTFP__) || defined(PPC) double SharedRuntime::dsqrt(double f) { return sqrt(f); } @@ -464,7 +472,7 @@ return (jdouble)x; JRT_END -// Exception handling across interpreter/compiler boundaries +// Exception handling accross interpreter/compiler boundaries // // exception_handler_for_return_address(...) returns the continuation address. // The continuation address is the entry point of the exception handler of the @@ -492,13 +500,6 @@ assert(!nm->is_native_method(), "no exception handler"); assert(nm->header_begin() != nm->exception_begin(), "no exception handler"); if (nm->is_deopt_pc(return_address)) { - // If we come here because of a stack overflow, the stack may be - // unguarded. Reguard the stack otherwise if we return to the - // deopt blob and the stack bang causes a stack overflow we - // crash. - bool guard_pages_enabled = thread->stack_yellow_zone_enabled(); - if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack(); - assert(guard_pages_enabled, "stack banging in deopt blob may cause crash"); return SharedRuntime::deopt_blob()->unpack_with_exception(); } else { return nm->exception_begin(); @@ -713,8 +714,8 @@ // Allow abbreviated catch tables. The idea is to allow a method // to materialize its exceptions without committing to the exact // routing of exceptions. In particular this is needed for adding - // a synthetic handler to unlock monitors when inlining - // synchronized methods since the unlock path isn't represented in + // a synthethic handler to unlock monitors when inlining + // synchonized methods since the unlock path isn't represented in // the bytecodes. t = table.entry_for(catch_pco, -1, 0); } @@ -852,7 +853,7 @@ // Exception happened in CodeCache. Must be either: // 1. Inline-cache check in C2I handler blob, // 2. Inline-cache check in nmethod, or - // 3. Implicit null exception in nmethod + // 3. Implict null exception in nmethod if (!cb->is_nmethod()) { bool is_in_blob = cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(); @@ -1026,9 +1027,14 @@ Klass* klass = o->klass(); int size = o->size(); Symbol* name = klass->name(); +#ifndef USDT2 + HS_DTRACE_PROBE4(hotspot, object__alloc, get_java_tid(thread), + name->bytes(), name->utf8_length(), size * HeapWordSize); +#else /* USDT2 */ HOTSPOT_OBJECT_ALLOC( get_java_tid(thread), (char *) name->bytes(), name->utf8_length(), size * HeapWordSize); +#endif /* USDT2 */ return 0; } @@ -1038,11 +1044,18 @@ Symbol* kname = method->klass_name(); Symbol* name = method->name(); Symbol* sig = method->signature(); +#ifndef USDT2 + HS_DTRACE_PROBE7(hotspot, method__entry, get_java_tid(thread), + kname->bytes(), kname->utf8_length(), + name->bytes(), name->utf8_length(), + sig->bytes(), sig->utf8_length()); +#else /* USDT2 */ HOTSPOT_METHOD_ENTRY( get_java_tid(thread), (char *) kname->bytes(), kname->utf8_length(), (char *) name->bytes(), name->utf8_length(), (char *) sig->bytes(), sig->utf8_length()); +#endif /* USDT2 */ return 0; JRT_END @@ -1052,11 +1065,18 @@ Symbol* kname = method->klass_name(); Symbol* name = method->name(); Symbol* sig = method->signature(); +#ifndef USDT2 + HS_DTRACE_PROBE7(hotspot, method__return, get_java_tid(thread), + kname->bytes(), kname->utf8_length(), + name->bytes(), name->utf8_length(), + sig->bytes(), sig->utf8_length()); +#else /* USDT2 */ HOTSPOT_METHOD_RETURN( get_java_tid(thread), (char *) kname->bytes(), kname->utf8_length(), (char *) name->bytes(), name->utf8_length(), (char *) sig->bytes(), sig->utf8_length()); +#endif /* USDT2 */ return 0; JRT_END @@ -2444,7 +2464,7 @@ ResourceMark rm; NOT_PRODUCT(int insts_size); - AdapterBlob* new_adapter = NULL; + AdapterBlob* B = NULL; AdapterHandlerEntry* entry = NULL; AdapterFingerPrint* fingerprint = NULL; { @@ -2476,8 +2496,7 @@ #ifdef ASSERT AdapterHandlerEntry* shared_entry = NULL; - // Start adapter sharing verification only after the VM is booted. - if (VerifyAdapterSharing && (entry != NULL)) { + if (VerifyAdapterSharing && entry != NULL) { shared_entry = entry; entry = NULL; } @@ -2493,44 +2512,41 @@ // Make a C heap allocated version of the fingerprint to store in the adapter fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); - // StubRoutines::code2() is initialized after this function can be called. As a result, - // VerifyAdapterCalls and VerifyAdapterSharing can fail if we re-use code that generated - // prior to StubRoutines::code2() being set. Checks refer to checks generated in an I2C - // stub that ensure that an I2C stub is called from an interpreter frame. - bool contains_all_checks = StubRoutines::code2() != NULL; - // Create I2C & C2I handlers + BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache if (buf != NULL) { CodeBuffer buffer(buf); short buffer_locs[20]; buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo)); - MacroAssembler _masm(&buffer); + entry = SharedRuntime::generate_i2c2i_adapters(&_masm, total_args_passed, comp_args_on_stack, sig_bt, regs, fingerprint); + #ifdef ASSERT if (VerifyAdapterSharing) { if (shared_entry != NULL) { - assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match"); + assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt), + "code must match"); // Release the one just created and return the original _adapters->free_entry(entry); return shared_entry; } else { - entry->save_code(buf->code_begin(), buffer.insts_size()); + entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt); } } #endif - new_adapter = AdapterBlob::create(&buffer); + B = AdapterBlob::create(&buffer); NOT_PRODUCT(insts_size = buffer.insts_size()); } - if (new_adapter == NULL) { + if (B == NULL) { // CodeCache is full, disable compilation // Ought to log this but compile log is only per compile thread // and we're some non descript Java thread. @@ -2538,7 +2554,7 @@ CompileBroker::handle_full_code_cache(); return NULL; // Out of CodeCache space } - entry->relocate(new_adapter->content_begin()); + entry->relocate(B->content_begin()); #ifndef PRODUCT // debugging suppport if (PrintAdapterHandlers || PrintStubCode) { @@ -2557,25 +2573,22 @@ } } #endif - // Add the entry only if the entry contains all required checks (see sharedRuntime_xxx.cpp) - // The checks are inserted only if -XX:+VerifyAdapterCalls is specified. - if (contains_all_checks || !VerifyAdapterCalls) { - _adapters->add(entry); - } + + _adapters->add(entry); } // Outside of the lock - if (new_adapter != NULL) { + if (B != NULL) { char blob_id[256]; jio_snprintf(blob_id, sizeof(blob_id), "%s(%s)@" PTR_FORMAT, - new_adapter->name(), + B->name(), fingerprint->as_string(), - new_adapter->content_begin()); - Forte::register_stub(blob_id, new_adapter->content_begin(),new_adapter->content_end()); + B->content_begin()); + Forte::register_stub(blob_id, B->content_begin(), B->content_end()); if (JvmtiExport::should_post_dynamic_code_generated()) { - JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end()); + JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end()); } } return entry; @@ -2607,6 +2620,7 @@ delete _fingerprint; #ifdef ASSERT if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); + if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode); #endif } @@ -2615,30 +2629,35 @@ // Capture the code before relocation so that it can be compared // against other versions. If the code is captured after relocation // then relative instructions won't be equivalent. -void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) { +void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); - _saved_code_length = length; + _code_length = length; memcpy(_saved_code, buffer, length); + _total_args_passed = total_args_passed; + _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode); + memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); } -bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) { - if (length != _saved_code_length) { +bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { + if (length != _code_length) { return false; } - - return (memcmp(buffer, _saved_code, length) == 0) ? true : false; + for (int i = 0; i < length; i++) { + if (buffer[i] != _saved_code[i]) { + return false; + } + } + return true; } #endif -/** - * Create a native wrapper for this native method. The wrapper converts the - * Java-compiled calling convention to the native convention, handles - * arguments, and transitions to native. On return from the native we transition - * back to java blocking if a safepoint is in progress. - */ -void AdapterHandlerLibrary::create_native_wrapper(methodHandle method) { +// Create a native wrapper for this native method. The wrapper converts the +// java compiled calling convention to the native convention, handlizes +// arguments, and transitions to native. On return from the native we transition +// back to java blocking if a safepoint is in progress. +nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) { ResourceMark rm; nmethod* nm = NULL; @@ -2647,19 +2666,16 @@ method->has_native_function(), "must have something valid to call!"); { - // Perform the work while holding the lock, but perform any printing outside the lock + // perform the work while holding the lock, but perform any printing outside the lock MutexLocker mu(AdapterHandlerLibrary_lock); // See if somebody beat us to it nm = method->code(); - if (nm != NULL) { - return; + if (nm) { + return nm; } - const int compile_id = CompileBroker::assign_compile_id(method, CompileBroker::standard_entry_bci); - assert(compile_id > 0, "Must generate native wrapper"); - - ResourceMark rm; + BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache if (buf != NULL) { CodeBuffer buffer(buf); @@ -2691,14 +2707,16 @@ int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing); // Generate the compiled-to-native wrapper code - nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type); - - if (nm != NULL) { - method->set_code(method, nm); - } + nm = SharedRuntime::generate_native_wrapper(&_masm, + method, + compile_id, + sig_bt, + regs, + ret_type); } - } // Unlock AdapterHandlerLibrary_lock - + } + + // Must unlock before calling set_code // Install the generated code. if (nm != NULL) { @@ -2706,11 +2724,13 @@ ttyLocker ttyl; CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : ""); } + method->set_code(method, nm); nm->post_compiled_method_load_event(); } else { // CodeCache is full, disable compilation CompileBroker::handle_full_code_cache(); } + return nm; } JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* thread)) @@ -2788,71 +2808,6 @@ } #endif // ndef HAVE_DTRACE_H -int SharedRuntime::convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) { - int argcnt = in_args_count; - if (CCallingConventionRequiresIntsAsLongs) { - for (int in = 0; in < in_args_count; in++) { - BasicType bt = in_sig_bt[in]; - switch (bt) { - case T_BOOLEAN: - case T_CHAR: - case T_BYTE: - case T_SHORT: - case T_INT: - argcnt++; - break; - default: - break; - } - } - } else { - assert(0, "This should not be needed on this platform"); - } - - return argcnt; -} - -void SharedRuntime::convert_ints_to_longints(int i2l_argcnt, int& in_args_count, - BasicType*& in_sig_bt, VMRegPair*& in_regs) { - if (CCallingConventionRequiresIntsAsLongs) { - VMRegPair *new_in_regs = NEW_RESOURCE_ARRAY(VMRegPair, i2l_argcnt); - BasicType *new_in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt); - - int argcnt = 0; - for (int in = 0; in < in_args_count; in++, argcnt++) { - BasicType bt = in_sig_bt[in]; - VMRegPair reg = in_regs[in]; - switch (bt) { - case T_BOOLEAN: - case T_CHAR: - case T_BYTE: - case T_SHORT: - case T_INT: - // Convert (bt) to (T_LONG,bt). - new_in_sig_bt[argcnt ] = T_LONG; - new_in_sig_bt[argcnt+1] = bt; - assert(reg.first()->is_valid() && !reg.second()->is_valid(), ""); - new_in_regs[argcnt ].set2(reg.first()); - new_in_regs[argcnt+1].set_bad(); - argcnt++; - break; - default: - // No conversion needed. - new_in_sig_bt[argcnt] = bt; - new_in_regs[argcnt] = reg; - break; - } - } - assert(argcnt == i2l_argcnt, "must match"); - - in_regs = new_in_regs; - in_sig_bt = new_in_sig_bt; - in_args_count = i2l_argcnt; - } else { - assert(0, "This should not be needed on this platform"); - } -} - // ------------------------------------------------------------------------- // Java-Java calling convention // (what you use when Java calls Java) @@ -2952,7 +2907,7 @@ // called from very start of a compiled OSR nmethod. A temp array is // allocated to hold the interesting bits of the interpreter frame. All // active locks are inflated to allow them to move. The displaced headers and -// active interpreter locals are copied into the temp buffer. Then we return +// active interpeter locals are copied into the temp buffer. Then we return // back to the compiled code. The compiled code then pops the current // interpreter frame off the stack and pushes a new compiled frame. Then it // copies the interpreter locals and displaced headers where it wants.