--- old/src/share/vm/oops/valueKlass.cpp 2017-06-20 16:28:37.018272017 -0400 +++ new/src/share/vm/oops/valueKlass.cpp 2017-06-20 16:28:36.418269042 -0400 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "gc/shared/gcLocker.inline.hpp" #include "interpreter/interpreter.hpp" +#include "logging/log.hpp" #include "oops/oop.inline.hpp" #include "oops/fieldStreams.hpp" #include "oops/method.hpp" @@ -86,6 +87,28 @@ return 1 << upper_log2(last_offset - first_offset); } +instanceOop ValueKlass::allocate_instance(TRAPS) { + int size = size_helper(); // Query before forming handle. + + return (instanceOop)CollectedHeap::obj_allocate(this, size, CHECK_NULL); +} + +instanceOop ValueKlass::allocate_buffered_or_heap_instance(bool* in_heap, TRAPS) { + assert(THREAD->is_Java_thread(), "Only Java threads can call this method"); + + instanceOop value = NULL; + if (is_bufferable()) { + value = (instanceOop)VTBuffer::allocate_value(this, CHECK_NULL); + *in_heap = false; + } + if (value == NULL) { + log_info(valuetypes)("Value buffering failed, allocating in the Java heap"); + value = allocate_instance(CHECK_NULL); + *in_heap = true; + } + return value; +} + bool ValueKlass::is_atomic() { return (nonstatic_field_size() * heapOopSize) <= longSize; } @@ -235,24 +258,29 @@ } } -oop ValueKlass::derive_value_type_copy(Handle src, InstanceKlass* target_klass, TRAPS) { - assert(EnableMVT, "Only supported with the MVT programming model"); - // assert(InstanceKlass::cast(src->klass())->derive_value_type_klass() == target_klass, "Not this DVT"); -#ifdef ASSERT - if (InstanceKlass::cast(src->klass())->has_vcc_klass()) { - assert(InstanceKlass::cast(src->klass())->get_vcc_klass() == target_klass, - "VCC/DVT mismatch"); - } else { - assert(target_klass->has_vcc_klass(), "Sanity check"); - assert(target_klass->get_vcc_klass() == InstanceKlass::cast(src->klass()), - "VCC/DVT mismatch"); - } -#endif // ASSERT +oop ValueKlass::box(Handle src, InstanceKlass* target_klass, TRAPS) { + assert(src()->klass()->is_value(), "src must be a value type"); + assert(!target_klass->is_value(), "target_klass must not be a value type"); - // Allocate new for safety, simply reinstalling the klass pointer is a little too risky target_klass->initialize(CHECK_0); - instanceOop value = target_klass->allocate_instance(CHECK_0); - value_store(data_for_oop(src()), data_for_oop(value), true, true); + instanceOop box = target_klass->allocate_instance(CHECK_0); + value_store(data_for_oop(src()), data_for_oop(box), true, false); + + assert(!box->klass()->is_value(), "Sanity check"); + return box; +} + +oop ValueKlass::unbox(Handle src, InstanceKlass* target_klass, TRAPS) { + assert(!src()->klass()->is_value(), "src must not be a value type"); + assert(target_klass->is_value(), "target_klass must be a value type"); + ValueKlass* vtklass = ValueKlass::cast(target_klass); + + vtklass->initialize(CHECK_0); + bool in_heap; + instanceOop value = vtklass->allocate_buffered_or_heap_instance(&in_heap, CHECK_0); + value_store(data_for_oop(src()), data_for_oop(value), in_heap, false); + + assert(value->klass()->is_value(), "Sanity check"); return value; } @@ -511,8 +539,13 @@ address loc = map.location(pair.first()); intptr_t ptr = *(intptr_t*)loc; - if (Universe::heap()->is_in_reserved((void*)ptr)) { - return NULL; + if (Metaspace::contains((void*)ptr)) { + return (ValueKlass*)ptr; } - return (ValueKlass*)ptr; + return NULL; +// if (Universe::heap()->is_in_reserved((void*)ptr)) { +// return NULL; +// } +// return (ValueKlass*)ptr; } +