# HG changeset patch # User lana # Date 1413392944 25200 # Node ID 312b5f1dc31d302381d99fb01bdf16626c259f58 # Parent 735b6a7be7dc008354fa2be6cec0714e6783336d# Parent 5d839e60d9f5afc3377fcb3d7df52794e18c1400 Merge diff -r 735b6a7be7dc -r 312b5f1dc31d make/bsd/makefiles/mapfile-vers-debug --- a/make/bsd/makefiles/mapfile-vers-debug Tue Oct 07 12:47:46 2014 -0700 +++ b/make/bsd/makefiles/mapfile-vers-debug Wed Oct 15 10:09:04 2014 -0700 @@ -158,6 +158,7 @@ _JVM_GetStackTraceElement _JVM_GetSystemPackage _JVM_GetSystemPackages + _JVM_GetTemporaryDirectory _JVM_GetThreadStateNames _JVM_GetThreadStateValues _JVM_GetVersionInfo diff -r 735b6a7be7dc -r 312b5f1dc31d make/bsd/makefiles/mapfile-vers-product --- a/make/bsd/makefiles/mapfile-vers-product Tue Oct 07 12:47:46 2014 -0700 +++ b/make/bsd/makefiles/mapfile-vers-product Wed Oct 15 10:09:04 2014 -0700 @@ -158,6 +158,7 @@ _JVM_GetStackTraceElement _JVM_GetSystemPackage _JVM_GetSystemPackages + _JVM_GetTemporaryDirectory _JVM_GetThreadStateNames _JVM_GetThreadStateValues _JVM_GetVersionInfo diff -r 735b6a7be7dc -r 312b5f1dc31d make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Tue Oct 07 12:47:46 2014 -0700 +++ b/make/linux/makefiles/mapfile-vers-debug Wed Oct 15 10:09:04 2014 -0700 @@ -123,7 +123,7 @@ JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; JVM_GetComponentType; JVM_GetDeclaredClasses; @@ -160,6 +160,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 735b6a7be7dc -r 312b5f1dc31d make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Tue Oct 07 12:47:46 2014 -0700 +++ b/make/linux/makefiles/mapfile-vers-product Wed Oct 15 10:09:04 2014 -0700 @@ -160,6 +160,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 735b6a7be7dc -r 312b5f1dc31d make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Tue Oct 07 12:47:46 2014 -0700 +++ b/make/solaris/makefiles/mapfile-vers Wed Oct 15 10:09:04 2014 -0700 @@ -160,6 +160,7 @@ JVM_GetStackTraceElement; JVM_GetSystemPackage; JVM_GetSystemPackages; + JVM_GetTemporaryDirectory; JVM_GetThreadStateNames; JVM_GetThreadStateValues; JVM_GetVersionInfo; diff -r 735b6a7be7dc -r 312b5f1dc31d src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Tue Oct 07 12:47:46 2014 -0700 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Oct 15 10:09:04 2014 -0700 @@ -1142,50 +1142,81 @@ // Hoist any int/ptr/long's in the first 6 to int regs. // Hoist any flt/dbl's in the first 16 dbl regs. int j = 0; // Count of actual args, not HALVES - for( int i=0; ias_VMReg()); - } else { - // V9ism: floats go in ODD stack slot - regs[i].set1(VMRegImpl::stack2reg(1 + (j<<1))); + // Per SPARC Compliance Definition 2.4.1, page 3P-12 available here + // http://www.sparc.org/wp-content/uploads/2014/01/SCD.2.4.1.pdf.gz + // + // "When a callee prototype exists, and does not indicate variable arguments, + // floating-point values assigned to locations %sp+BIAS+128 through %sp+BIAS+248 + // will be promoted to floating-point registers" + // + // By "promoted" it means that the argument is located in two places, an unused + // spill slot in the "parameter array" (starts at %sp+BIAS+128), and a live + // float register. In most cases, there are 6 or fewer arguments of any type, + // and the standard parameter array slots (%sp+BIAS+128 to %sp+BIAS+176 exclusive) + // serve as shadow slots. Per the spec floating point registers %d6 to %d16 + // require slots beyond that (up to %sp+BIAS+248). + // + { + // V9ism: floats go in ODD registers and stack slots + int float_index = 1 + (j << 1); + param_array_reg.set1(VMRegImpl::stack2reg(float_index)); + if (j < 16) { + regs[i].set1(as_FloatRegister(float_index)->as_VMReg()); + } else { + regs[i] = param_array_reg; + } } break; case T_DOUBLE: - assert( sig_bt[i+1] == T_VOID, "expecting half" ); - if ( j < 16 ) { - // V9ism: doubles go in EVEN/ODD regs - regs[i].set2(as_FloatRegister(j<<1)->as_VMReg()); - } else { - // V9ism: doubles go in EVEN/ODD stack slots - regs[i].set2(VMRegImpl::stack2reg(j<<1)); + { + assert(sig_bt[i + 1] == T_VOID, "expecting half"); + // V9ism: doubles go in EVEN/ODD regs and stack slots + int double_index = (j << 1); + param_array_reg.set2(VMRegImpl::stack2reg(double_index)); + if (j < 16) { + regs[i].set2(as_FloatRegister(double_index)->as_VMReg()); + } else { + // V9ism: doubles go in EVEN/ODD stack slots + regs[i] = param_array_reg; + } } break; - case T_VOID: regs[i].set_bad(); j--; break; // Do not count HALVES + case T_VOID: + regs[i].set_bad(); + j--; + break; // Do not count HALVES default: ShouldNotReachHere(); } - if (regs[i].first()->is_stack()) { - int off = regs[i].first()->reg2stack(); + // Keep track of the deepest parameter array slot. + if (!param_array_reg.first()->is_valid()) { + param_array_reg = regs[i]; + } + if (param_array_reg.first()->is_stack()) { + int off = param_array_reg.first()->reg2stack(); if (off > max_stack_slots) max_stack_slots = off; } - if (regs[i].second()->is_stack()) { - int off = regs[i].second()->reg2stack(); + if (param_array_reg.second()->is_stack()) { + int off = param_array_reg.second()->reg2stack(); if (off > max_stack_slots) max_stack_slots = off; } } @@ -1193,8 +1224,8 @@ #else // _LP64 // V8 convention: first 6 things in O-regs, rest on stack. // Alignment is willy-nilly. - for( int i=0; iis_stack()) { - int off = regs[i].first()->reg2stack(); + int off = regs[i].first()->reg2stack(); if (off > max_stack_slots) max_stack_slots = off; } if (regs[i].second()->is_stack()) { - int off = regs[i].second()->reg2stack(); + int off = regs[i].second()->reg2stack(); if (off > max_stack_slots) max_stack_slots = off; } } @@ -1369,11 +1400,10 @@ const Register rOop = src.first()->as_Register(); const Register rHandle = L5; int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset; - int offset = oop_slot*VMRegImpl::stack_slot_size; - Label skip; + int offset = oop_slot * VMRegImpl::stack_slot_size; __ st_ptr(rOop, SP, offset + STACK_BIAS); if (is_receiver) { - *receiver_offset = oop_slot * VMRegImpl::stack_slot_size; + *receiver_offset = offset; } map->set_oop(VMRegImpl::stack2reg(oop_slot)); __ add(SP, offset + STACK_BIAS, rHandle); diff -r 735b6a7be7dc -r 312b5f1dc31d src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Tue Oct 07 12:47:46 2014 -0700 +++ b/src/cpu/sparc/vm/sparc.ad Wed Oct 15 10:09:04 2014 -0700 @@ -1978,7 +1978,7 @@ // to implement the UseStrictFP mode. const bool Matcher::strict_fp_requires_explicit_rounding = false; -// Are floats conerted to double when stored to stack during deoptimization? +// Are floats converted to double when stored to stack during deoptimization? // Sparc does not handle callee-save floats. bool Matcher::float_in_double() { return false; } @@ -3216,7 +3216,7 @@ // are owned by the CALLEE. Holes should not be nessecary in the // incoming area, as the Java calling convention is completely under // the control of the AD file. Doubles can be sorted and packed to -// avoid holes. Holes in the outgoing arguments may be nessecary for +// avoid holes. Holes in the outgoing arguments may be necessary for // varargs C calling conventions. // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is // even aligned with pad0 as needed. @@ -3282,7 +3282,7 @@ %} // Body of function which returns an OptoRegs array locating - // arguments either in registers or in stack slots for callin + // arguments either in registers or in stack slots for calling // C. c_calling_convention %{ // This is obviously always outgoing diff -r 735b6a7be7dc -r 312b5f1dc31d src/cpu/x86/vm/frame_x86.inline.hpp --- a/src/cpu/x86/vm/frame_x86.inline.hpp Tue Oct 07 12:47:46 2014 -0700 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp Wed Oct 15 10:09:04 2014 -0700 @@ -292,14 +292,18 @@ return true; } - +inline oop frame::saved_oop_result(RegisterMap* map) const { + oop* result_adr = (oop *)map->location(rax->as_VMReg()); + guarantee(result_adr != NULL, "bad register save location"); -inline oop frame::saved_oop_result(RegisterMap* map) const { - return *((oop*) map->location(rax->as_VMReg())); + return (*result_adr); } inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { - *((oop*) map->location(rax->as_VMReg())) = obj; + oop* result_adr = (oop *)map->location(rax->as_VMReg()); + guarantee(result_adr != NULL, "bad register save location"); + + *result_adr = obj; } #endif // CPU_X86_VM_FRAME_X86_INLINE_HPP diff -r 735b6a7be7dc -r 312b5f1dc31d src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Oct 07 12:47:46 2014 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Oct 15 10:09:04 2014 -0700 @@ -2752,10 +2752,12 @@ } } -void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { - assert(fl->count() == 0, "Precondition."); - assert(word_sz < CompactibleFreeListSpace::IndexSetSize, - "Precondition"); +// Used by par_get_chunk_of_blocks() for the chunks from the +// indexed_free_lists. Looks for a chunk with size that is a multiple +// of "word_sz" and if found, splits it into "word_sz" chunks and add +// to the free list "fl". "n" is the maximum number of chunks to +// be added to "fl". +bool CompactibleFreeListSpace:: par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, FreeList* fl) { // We'll try all multiples of word_sz in the indexed set, starting with // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples, @@ -2836,11 +2838,15 @@ Mutex::_no_safepoint_check_flag); ssize_t births = _indexedFreeList[word_sz].split_births() + num; _indexedFreeList[word_sz].set_split_births(births); - return; + return true; } } + return found; } - // Otherwise, we'll split a block from the dictionary. +} + +FreeChunk* CompactibleFreeListSpace::get_n_way_chunk_to_split(size_t word_sz, size_t n) { + FreeChunk* fc = NULL; FreeChunk* rem_fc = NULL; size_t rem; @@ -2852,16 +2858,12 @@ _dictionary->min_size()), FreeBlockDictionary::atLeast); if (fc != NULL) { - _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk - dictionary()->dict_census_udpate(fc->size(), - true /*split*/, - false /*birth*/); break; } else { n--; } } - if (fc == NULL) return; + if (fc == NULL) return NULL; // Otherwise, split up that block. assert((ssize_t)n >= 1, "Control point invariant"); assert(fc->is_free(), "Error: should be a free block"); @@ -2883,10 +2885,14 @@ // dictionary and return, leaving "fl" empty. if (n == 0) { returnChunkToDictionary(fc); - assert(fl->count() == 0, "We never allocated any blocks"); - return; + return NULL; } + _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk + dictionary()->dict_census_udpate(fc->size(), + true /*split*/, + false /*birth*/); + // First return the remainder, if any. // Note that we hold the lock until we decide if we're going to give // back the remainder to the dictionary, since a concurrent allocation @@ -2919,7 +2925,24 @@ _indexedFreeList[rem].return_chunk_at_head(rem_fc); smallSplitBirth(rem); } - assert((ssize_t)n > 0 && fc != NULL, "Consistency"); + assert(n * word_sz == fc->size(), + err_msg("Chunk size " SIZE_FORMAT " is not exactly splittable by " + SIZE_FORMAT " sized chunks of size " SIZE_FORMAT, + fc->size(), n, word_sz)); + return fc; +} + +void CompactibleFreeListSpace:: par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t targetted_number_of_chunks, FreeList* fl) { + + FreeChunk* fc = get_n_way_chunk_to_split(word_sz, targetted_number_of_chunks); + + if (fc == NULL) { + return; + } + + size_t n = fc->size() / word_sz; + + assert((ssize_t)n > 0, "Consistency"); // Now do the splitting up. // Must do this in reverse order, so that anybody attempting to // access the main chunk sees it as a single free block until we @@ -2967,6 +2990,20 @@ assert(fl->tail()->next() == NULL, "List invariant."); } +void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { + assert(fl->count() == 0, "Precondition."); + assert(word_sz < CompactibleFreeListSpace::IndexSetSize, + "Precondition"); + + if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) { + // Got it + return; + } + + // Otherwise, we'll split a block from the dictionary. + par_get_chunk_of_blocks_dictionary(word_sz, n, fl); +} + // Set up the space's par_seq_tasks structure for work claiming // for parallel rescan. See CMSParRemarkTask where this is currently used. // XXX Need to suitably abstract and generalize this and the next diff -r 735b6a7be7dc -r 312b5f1dc31d src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Oct 07 12:47:46 2014 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Wed Oct 15 10:09:04 2014 -0700 @@ -171,6 +171,20 @@ // list of size "word_sz", and must now be decremented. void par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl); + // Used by par_get_chunk_of_blocks() for the chunks from the + // indexed_free_lists. + bool par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, FreeList* fl); + + // Used by par_get_chunk_of_blocks_dictionary() to get a chunk + // evenly splittable into "n" "word_sz" chunks. Returns that + // evenly splittable chunk. May split a larger chunk to get the + // evenly splittable chunk. + FreeChunk* get_n_way_chunk_to_split(size_t word_sz, size_t n); + + // Used by par_get_chunk_of_blocks() for the chunks from the + // dictionary. + void par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t n, FreeList* fl); + // Allocation helper functions // Allocate using a strategy that takes from the indexed free lists // first. This allocation strategy assumes a companion sweeping diff -r 735b6a7be7dc -r 312b5f1dc31d src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Tue Oct 07 12:47:46 2014 -0700 +++ b/src/share/vm/prims/jvm.cpp Wed Oct 15 10:09:04 2014 -0700 @@ -388,6 +388,23 @@ JVM_END +/* + * Return the temporary directory that the VM uses for the attach + * and perf data files. + * + * It is important that this directory is well-known and the + * same for all VM instances. It cannot be affected by configuration + * variables such as java.io.tmpdir. + */ +JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env)) + JVMWrapper("JVM_GetTemporaryDirectory"); + HandleMark hm(THREAD); + const char* temp_dir = os::get_temp_directory(); + Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL); + return (jstring) JNIHandles::make_local(env, h()); +JVM_END + + // java.lang.Runtime ///////////////////////////////////////////////////////////////////////// extern volatile jint vm_created; diff -r 735b6a7be7dc -r 312b5f1dc31d src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Tue Oct 07 12:47:46 2014 -0700 +++ b/src/share/vm/prims/jvm.h Wed Oct 15 10:09:04 2014 -0700 @@ -1477,6 +1477,9 @@ JNIEXPORT jobject JNICALL JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); +JNIEXPORT jstring JNICALL +JVM_GetTemporaryDirectory(JNIEnv *env); + /* Generics reflection support. * * Returns information about the given class's EnclosingMethod