Mercurial > hg > graal-jvmci-8
diff src/share/vm/jvmci/jvmciCodeInstaller.cpp @ 22711:316e768645c0
8139589: [JVMCI] throw exceptions in faulty code installation operations
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Thu, 29 Oct 2015 15:21:55 +0100 |
parents | 15013021dbfa |
children | 3c0753fbb592 |
line wrap: on
line diff
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp Thu Oct 29 13:13:46 2015 +0100 +++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp Thu Oct 29 15:21:55 2015 +0100 @@ -69,62 +69,81 @@ return CompilerToVM::asMethod(hotspot_method); } -VMReg getVMRegFromLocation(oop location, int total_frame_size) { - oop reg = code_Location::reg(location); +VMReg getVMRegFromLocation(Handle location, int total_frame_size, TRAPS) { + Handle reg = code_Location::reg(location); jint offset = code_Location::offset(location); - if (reg != NULL) { + if (reg.not_null()) { // register jint number = code_Register::number(reg); - VMReg vmReg = CodeInstaller::get_hotspot_reg(number); - assert(offset % 4 == 0, "must be aligned"); - return vmReg->next(offset / 4); + VMReg vmReg = CodeInstaller::get_hotspot_reg(number, CHECK_NULL); + if (offset % 4 == 0) { + return vmReg->next(offset / 4); + } else { + JVMCI_ERROR_NULL(err_msg("unaligned subregister offset %d in oop map", offset)); + } } else { // stack slot - assert(offset % 4 == 0, "must be aligned"); - return VMRegImpl::stack2reg(offset / 4); + if (offset % 4 == 0) { + return VMRegImpl::stack2reg(offset / 4); + } else { + JVMCI_ERROR_NULL(err_msg("unaligned stack offset %d in oop map", offset)); + } } } // creates a HotSpot oop map out of the byte arrays provided by DebugInfo -OopMap* CodeInstaller::create_oop_map(oop debug_info) { - oop reference_map = DebugInfo::referenceMap(debug_info); +OopMap* CodeInstaller::create_oop_map(Handle debug_info, TRAPS) { + Handle reference_map = DebugInfo::referenceMap(debug_info); if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) { _has_wide_vector = true; } OopMap* map = new OopMap(_total_frame_size, _parameter_count); - objArrayOop objects = HotSpotReferenceMap::objects(reference_map); - objArrayOop derivedBase = HotSpotReferenceMap::derivedBase(reference_map); - typeArrayOop sizeInBytes = HotSpotReferenceMap::sizeInBytes(reference_map); + objArrayHandle objects = HotSpotReferenceMap::objects(reference_map); + objArrayHandle derivedBase = HotSpotReferenceMap::derivedBase(reference_map); + typeArrayHandle sizeInBytes = HotSpotReferenceMap::sizeInBytes(reference_map); for (int i = 0; i < objects->length(); i++) { - oop location = objects->obj_at(i); - oop baseLocation = derivedBase->obj_at(i); + Handle location = objects->obj_at(i); + Handle baseLocation = derivedBase->obj_at(i); int bytes = sizeInBytes->int_at(i); - VMReg vmReg = getVMRegFromLocation(location, _total_frame_size); - if (baseLocation != NULL) { + VMReg vmReg = getVMRegFromLocation(location, _total_frame_size, CHECK_NULL); + if (baseLocation.not_null()) { // derived oop - assert(bytes == 8, "derived oop can't be compressed"); - VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size); - map->set_derived_oop(vmReg, baseReg); +#ifdef _LP64 + if (bytes == 8) { +#else + if (bytes == 4) { +#endif + VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size, CHECK_NULL); + map->set_derived_oop(vmReg, baseReg); + } else { + JVMCI_ERROR_NULL(err_msg("invalid derived oop size in ReferenceMap: %d", bytes)); + } +#ifdef _LP64 } else if (bytes == 8) { // wide oop map->set_oop(vmReg); - } else { + } else if (bytes == 4) { // narrow oop - assert(bytes == 4, "wrong size"); map->set_narrowoop(vmReg); +#else + } else if (bytes == 4) { + map->set_oop(vmReg); +#endif + } else { + JVMCI_ERROR_NULL(err_msg("invalid oop size in ReferenceMap: %d", bytes)); } } - oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); - if (callee_save_info != NULL) { - objArrayOop registers = RegisterSaveLayout::registers(callee_save_info); - typeArrayOop slots = RegisterSaveLayout::slots(callee_save_info); + Handle callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); + if (callee_save_info.not_null()) { + objArrayHandle registers = RegisterSaveLayout::registers(callee_save_info); + typeArrayHandle slots = RegisterSaveLayout::slots(callee_save_info); for (jint i = 0; i < slots->length(); i++) { - oop jvmci_reg = registers->obj_at(i); + Handle jvmci_reg = registers->obj_at(i); jint jvmci_reg_number = code_Register::number(jvmci_reg); - VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number); + VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, CHECK_NULL); // HotSpot stack slots are 4 bytes jint jvmci_slot = slots->int_at(i); jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word; @@ -140,7 +159,7 @@ return map; } -Metadata* CodeInstaller::record_metadata_reference(Handle& constant) { +Metadata* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant); if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) { Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); @@ -155,16 +174,18 @@ TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string()); return method; } else { - fatal(err_msg("unexpected metadata reference for constant of type %s", obj->klass()->name()->as_C_string())); - return NULL; + JVMCI_ERROR_NULL(err_msg("unexpected metadata reference for constant of type %s", obj->klass()->signature_name())); } } #ifdef _LP64 -narrowKlass CodeInstaller::record_narrow_metadata_reference(Handle& constant) { +narrowKlass CodeInstaller::record_narrow_metadata_reference(Handle constant, TRAPS) { oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant); assert(HotSpotMetaspaceConstantImpl::compressed(constant), err_msg("unexpected uncompressed pointer")); - assert(obj->is_a(HotSpotResolvedObjectTypeImpl::klass()), err_msg("unexpected compressed pointer of type %s", obj->klass()->name()->as_C_string())); + + if (!obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) { + JVMCI_ERROR_0(err_msg("unexpected compressed pointer of type %s", obj->klass()->signature_name())); + } Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); int index = _oop_recorder->find_index(klass); @@ -173,9 +194,9 @@ } #endif -Location::Type CodeInstaller::get_oop_type(oop value) { - oop lirKind = Value::lirKind(value); - oop platformKind = LIRKind::platformKind(lirKind); +Location::Type CodeInstaller::get_oop_type(Handle value) { + Handle lirKind = Value::lirKind(value); + Handle platformKind = LIRKind::platformKind(lirKind); assert(LIRKind::referenceMask(lirKind) == 1, "unexpected referenceMask"); if (platformKind == word_kind()) { @@ -185,24 +206,27 @@ } } -ScopeValue* CodeInstaller::get_scope_value(oop value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) { +ScopeValue* CodeInstaller::get_scope_value(Handle value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, TRAPS) { second = NULL; if (value == Value::ILLEGAL()) { - assert(type == T_ILLEGAL, "expected legal value"); + if (type != T_ILLEGAL) { + JVMCI_ERROR_NULL(err_msg("unexpected illegal value, expected %s", basictype_to_str(type))); + } return _illegal_value; } else if (value->is_a(RegisterValue::klass())) { - oop reg = RegisterValue::reg(value); + Handle reg = RegisterValue::reg(value); jint number = code_Register::number(reg); - VMReg hotspotRegister = get_hotspot_reg(number); + VMReg hotspotRegister = get_hotspot_reg(number, CHECK_NULL); if (is_general_purpose_reg(hotspotRegister)) { Location::Type locationType; if (type == T_OBJECT) { locationType = get_oop_type(value); } else if (type == T_LONG) { locationType = Location::lng; + } else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) { + locationType = Location::int_in_long; } else { - assert(type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN, "unexpected type in cpu register"); - locationType = Location::int_in_long; + JVMCI_ERROR_NULL(err_msg("unexpected type %s in cpu register", basictype_to_str(type))); } ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister)); if (type == T_LONG) { @@ -210,13 +234,14 @@ } return value; } else { - assert(type == T_FLOAT || type == T_DOUBLE, "only float and double expected in xmm register"); Location::Type locationType; if (type == T_FLOAT) { // this seems weird, but the same value is used in c1_LinearScan locationType = Location::normal; + } else if (type == T_DOUBLE) { + locationType = Location::dbl; } else { - locationType = Location::dbl; + JVMCI_ERROR_NULL(err_msg("unexpected type %s in floating point register", basictype_to_str(type))); } ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister)); if (type == T_DOUBLE) { @@ -237,9 +262,10 @@ locationType = Location::lng; } else if (type == T_DOUBLE) { locationType = Location::dbl; + } else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) { + locationType = Location::normal; } else { - assert(type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN, "unexpected type in stack slot"); - locationType = Location::normal; + JVMCI_ERROR_NULL(err_msg("unexpected type %s in stack slot", basictype_to_str(type))); } ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset)); if (type == T_DOUBLE || type == T_LONG) { @@ -252,7 +278,10 @@ jlong prim = PrimitiveConstant::primitive(value); return new ConstantLongValue(prim); } else { - assert(type == JVMCIRuntime::kindToBasicType(JavaKind::typeChar(PrimitiveConstant::kind(value))), "primitive constant type doesn't match"); + BasicType constantType = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(PrimitiveConstant::kind(value))); + if (type != constantType) { + JVMCI_ERROR_NULL(err_msg("primitive constant type doesn't match, expected %s but got %s", basictype_to_str(type), basictype_to_str(constantType))); + } if (type == T_INT || type == T_FLOAT) { jint prim = (jint)PrimitiveConstant::primitive(value); switch (prim) { @@ -262,53 +291,63 @@ case 2: return _int_2_scope_value; default: return new ConstantIntValue(prim); } - } else { - assert(type == T_LONG || type == T_DOUBLE, "unexpected primitive constant type"); + } else if (type == T_LONG || type == T_DOUBLE) { jlong prim = PrimitiveConstant::primitive(value); second = _int_1_scope_value; return new ConstantLongValue(prim); + } else { + JVMCI_ERROR_NULL(err_msg("unexpected primitive constant type %s", basictype_to_str(type))); } } - } else { - assert(type == T_OBJECT, "unexpected object constant"); - if (value->is_a(NullConstant::klass()) || value->is_a(HotSpotCompressedNullConstant::klass())) { + } else if (value->is_a(NullConstant::klass()) || value->is_a(HotSpotCompressedNullConstant::klass())) { + if (type == T_OBJECT) { return _oop_null_scope_value; } else { - assert(value->is_a(HotSpotObjectConstantImpl::klass()), "unexpected constant type"); + JVMCI_ERROR_NULL(err_msg("unexpected null constant, expected %s", basictype_to_str(type))); + } + } else if (value->is_a(HotSpotObjectConstantImpl::klass())) { + if (type == T_OBJECT) { oop obj = HotSpotObjectConstantImpl::object(value); - assert(obj != NULL, "null value must be in NullConstant"); + if (obj == NULL) { + JVMCI_ERROR_NULL("null value must be in NullConstant"); + } return new ConstantOopWriteValue(JNIHandles::make_local(obj)); + } else { + JVMCI_ERROR_NULL(err_msg("unexpected object constant, expected %s", basictype_to_str(type))); } } } else if (value->is_a(VirtualObject::klass())) { - assert(type == T_OBJECT, "unexpected virtual object"); - int id = VirtualObject::id(value); - ScopeValue* object = objects->at(id); - assert(object != NULL, "missing value"); - return object; - } else { - value->klass()->print(); - value->print(); + if (type == T_OBJECT) { + int id = VirtualObject::id(value); + if (0 <= id && id < objects->length()) { + ScopeValue* object = objects->at(id); + if (object != NULL) { + return object; + } + } + JVMCI_ERROR_NULL(err_msg("unknown virtual object id %d", id)); + } else { + JVMCI_ERROR_NULL(err_msg("unexpected virtual object, expected %s", basictype_to_str(type))); + } } - ShouldNotReachHere(); - return NULL; + + JVMCI_ERROR_NULL(err_msg("unexpected value in scope: %s", value->klass()->signature_name())) } -void CodeInstaller::record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects) { - oop type = VirtualObject::type(value); +void CodeInstaller::record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS) { + Handle type = VirtualObject::type(value); int id = VirtualObject::id(value); oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); Klass* klass = java_lang_Class::as_Klass(javaMirror); bool isLongArray = klass == Universe::longArrayKlassObj(); - objArrayOop values = VirtualObject::values(value); - objArrayOop slotKinds = VirtualObject::slotKinds(value); + objArrayHandle values = VirtualObject::values(value); + objArrayHandle slotKinds = VirtualObject::slotKinds(value); for (jint i = 0; i < values->length(); i++) { ScopeValue* cur_second = NULL; - oop object = values->obj_at(i); - oop kind = slotKinds->obj_at(i); - BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind)); - ScopeValue* value = get_scope_value(object, type, objects, cur_second); + Handle object = values->obj_at(i); + BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(slotKinds->obj_at(i))); + ScopeValue* value = get_scope_value(object, type, objects, cur_second, CHECK); if (isLongArray && cur_second == NULL) { // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. @@ -324,14 +363,16 @@ } } -MonitorValue* CodeInstaller::get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects) { - guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type StackLockValue"); +MonitorValue* CodeInstaller::get_monitor_value(Handle value, GrowableArray<ScopeValue*>* objects, TRAPS) { + if (!value->is_a(StackLockValue::klass())) { + JVMCI_ERROR_NULL(err_msg("Monitors must be of type StackLockValue, got %s", value->klass()->signature_name())); + } ScopeValue* second = NULL; - ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), T_OBJECT, objects, second); + ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), T_OBJECT, objects, second, CHECK_NULL); assert(second == NULL, "monitor cannot occupy two stack slots"); - ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), T_LONG, objects, second); + ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), T_LONG, objects, second, CHECK_NULL); assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); assert(lock_data_value->is_location(), "invalid monitor location"); Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); @@ -344,7 +385,7 @@ return new MonitorValue(owner_value, lock_data_loc, eliminated); } -void CodeInstaller::initialize_dependencies(oop compiled_code) { +void CodeInstaller::initialize_dependencies(oop compiled_code, TRAPS) { JavaThread* thread = JavaThread::current(); CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL; _oop_recorder = new OopRecorder(&_arena, true); @@ -366,8 +407,7 @@ } else if (assumption->klass() == Assumptions_CallSiteTargetValue::klass()) { assumption_CallSiteTargetValue(assumption); } else { - assumption->print(); - fatal("unexpected Assumption subclass"); + JVMCI_ERROR(err_msg("unexpected Assumption subclass %s", assumption->klass()->signature_name())); } } } @@ -386,17 +426,17 @@ } // constructor used to create a method -JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Handle target, Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log) { +JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Handle target, Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log, TRAPS) { CodeBuffer buffer("JVMCI Compiler CodeBuffer"); jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); - initialize_dependencies(JNIHandles::resolve(compiled_code_obj)); + initialize_dependencies(JNIHandles::resolve(compiled_code_obj), CHECK_OK); // Get instructions and constants CodeSections early because we need it. _instructions = buffer.insts(); _constants = buffer.consts(); - initialize_fields(target(), JNIHandles::resolve(compiled_code_obj)); - JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer); + initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK); + JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK); if (result != JVMCIEnv::ok) { return result; } @@ -439,7 +479,7 @@ return result; } -void CodeInstaller::initialize_fields(oop target, oop compiled_code) { +void CodeInstaller::initialize_fields(oop target, oop compiled_code, TRAPS) { if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) { Handle hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code); methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod()); @@ -460,7 +500,9 @@ // Pre-calculate the constants section size. This is required for PC-relative addressing. _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code)); - guarantee(HotSpotCompiledCode::dataSectionAlignment(compiled_code) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + if ((_constants->alignment() % HotSpotCompiledCode::dataSectionAlignment(compiled_code)) != 0) { + JVMCI_ERROR(err_msg("invalid data section alignment: %d", HotSpotCompiledCode::dataSectionAlignment(compiled_code))); + } _constants_size = data_section()->length(); _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code)); @@ -477,7 +519,7 @@ _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch)); } -int CodeInstaller::estimate_stubs_size() { +int CodeInstaller::estimate_stubs_size(TRAPS) { // Estimate the number of static call stubs that might be emitted. int static_call_stubs = 0; objArrayOop sites = this->sites(); @@ -486,7 +528,9 @@ if (site->is_a(CompilationResult_Mark::klass())) { oop id_obj = CompilationResult_Mark::id(site); if (id_obj != NULL) { - assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); + if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) { + JVMCI_ERROR_0(err_msg("expected Integer id, got %s", id_obj->klass()->signature_name())); + } jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); if (id == INVOKESTATIC || id == INVOKESPECIAL) { static_call_stubs++; @@ -498,7 +542,7 @@ } // perform data and call relocation on the CodeBuffer -JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer) { +JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, TRAPS) { HandleMark hm; objArrayHandle sites = this->sites(); int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo)); @@ -507,7 +551,7 @@ // stubs. Stubs have extra relocs but they are managed by the stub // section itself so they don't need to be accounted for in the // locs_buffer above. - int stubs_size = estimate_stubs_size(); + int stubs_size = estimate_stubs_size(CHECK_OK); int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment()); if (total_size > JVMCINMethodSizeLimit) { @@ -540,18 +584,20 @@ for (int i = 0; i < data_section_patches()->length(); i++) { Handle patch = data_section_patches()->obj_at(i); Handle reference = CompilationResult_DataPatch::reference(patch); - assert(reference->is_a(CompilationResult_ConstantReference::klass()), err_msg("patch in data section must be a ConstantReference")); + if (!reference->is_a(CompilationResult_ConstantReference::klass())) { + JVMCI_ERROR_OK(err_msg("invalid patch in data section: %s", reference->klass()->signature_name())); + } Handle constant = CompilationResult_ConstantReference::constant(reference); address dest = _constants->start() + CompilationResult_Site::pcOffset(patch); if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { if (HotSpotMetaspaceConstantImpl::compressed(constant)) { #ifdef _LP64 - *((narrowKlass*) dest) = record_narrow_metadata_reference(constant); + *((narrowKlass*) dest) = record_narrow_metadata_reference(constant, CHECK_OK); #else - fatal("unexpected compressed Klass* in 32-bit mode"); + JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode"); #endif } else { - *((Metadata**) dest) = record_metadata_reference(constant); + *((Metadata**) dest) = record_metadata_reference(constant, CHECK_OK); } } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { Handle obj = HotSpotObjectConstantImpl::object(constant); @@ -562,48 +608,45 @@ #ifdef _LP64 _constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const); #else - fatal("unexpected compressed oop in 32-bit mode"); + JVMCI_ERROR_OK("unexpected compressed oop in 32-bit mode"); #endif } else { _constants->relocate(dest, oop_Relocation::spec(oop_index)); } } else { - ShouldNotReachHere(); + JVMCI_ERROR_OK(err_msg("invalid constant in data section: %s", constant->klass()->signature_name())); } } jint last_pc_offset = -1; for (int i = 0; i < sites->length(); i++) { - { - No_Safepoint_Verifier no_safepoint; - oop site = sites->obj_at(i); - jint pc_offset = CompilationResult_Site::pcOffset(site); + Handle site = sites->obj_at(i); + jint pc_offset = CompilationResult_Site::pcOffset(site); - if (site->is_a(CompilationResult_Call::klass())) { - TRACE_jvmci_4("call at %i", pc_offset); - site_Call(buffer, pc_offset, site); - } else if (site->is_a(CompilationResult_Infopoint::klass())) { - // three reasons for infopoints denote actual safepoints - oop reason = CompilationResult_Infopoint::reason(site); - if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { - TRACE_jvmci_4("safepoint at %i", pc_offset); - site_Safepoint(buffer, pc_offset, site); - } else { - // if the infopoint is not an actual safepoint, it must have one of the other reasons - // (safeguard against new safepoint types that require handling above) - assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, ""); - site_Infopoint(buffer, pc_offset, site); - } - } else if (site->is_a(CompilationResult_DataPatch::klass())) { - TRACE_jvmci_4("datapatch at %i", pc_offset); - site_DataPatch(buffer, pc_offset, site); - } else if (site->is_a(CompilationResult_Mark::klass())) { - TRACE_jvmci_4("mark at %i", pc_offset); - site_Mark(buffer, pc_offset, site); - } else { - fatal("unexpected Site subclass"); - } - last_pc_offset = pc_offset; + if (site->is_a(CompilationResult_Call::klass())) { + TRACE_jvmci_4("call at %i", pc_offset); + site_Call(buffer, pc_offset, site, CHECK_OK); + } else if (site->is_a(CompilationResult_Infopoint::klass())) { + // three reasons for infopoints denote actual safepoints + oop reason = CompilationResult_Infopoint::reason(site); + if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { + TRACE_jvmci_4("safepoint at %i", pc_offset); + site_Safepoint(buffer, pc_offset, site, CHECK_OK); + } else if (InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason) { + site_Infopoint(buffer, pc_offset, site, CHECK_OK); + } else { + JVMCI_ERROR_OK(err_msg("unknown infopoint reason at %i", pc_offset)); + } + } else if (site->is_a(CompilationResult_DataPatch::klass())) { + TRACE_jvmci_4("datapatch at %i", pc_offset); + site_DataPatch(buffer, pc_offset, site, CHECK_OK); + } else if (site->is_a(CompilationResult_Mark::klass())) { + TRACE_jvmci_4("mark at %i", pc_offset); + site_Mark(buffer, pc_offset, site, CHECK_OK); + } else { + JVMCI_ERROR_OK(err_msg("unexpected site subclass: %s", site->klass()->signature_name())); } + last_pc_offset = pc_offset; + if (CodeInstallSafepointChecks && SafepointSynchronize::do_call_back()) { // this is a hacky way to force a safepoint check but nothing else was jumping out at me. ThreadToNativeFromVM ttnfv(JavaThread::current()); @@ -612,7 +655,6 @@ #ifndef PRODUCT if (comments() != NULL) { - No_Safepoint_Verifier no_safepoint; for (int i = 0; i < comments()->length(); i++) { oop comment = comments()->obj_at(i); assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce"); @@ -698,56 +740,61 @@ return true; } -GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(oop debug_info) { - objArrayOop virtualObjects = DebugInfo::virtualObjectMapping(debug_info); - if (virtualObjects == NULL) { +GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(Handle debug_info, TRAPS) { + objArrayHandle virtualObjects = DebugInfo::virtualObjectMapping(debug_info); + if (virtualObjects.is_null()) { return NULL; } GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(virtualObjects->length(), virtualObjects->length(), NULL); // Create the unique ObjectValues for (int i = 0; i < virtualObjects->length(); i++) { - oop value = virtualObjects->obj_at(i); + Handle value = virtualObjects->obj_at(i); int id = VirtualObject::id(value); - oop type = VirtualObject::type(value); + Handle type = VirtualObject::type(value); oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror))); - assert(objects->at(id) == NULL, "once"); + if (id < 0 || id >= objects->length()) { + JVMCI_ERROR_NULL(err_msg("virtual object id %d out of bounds", id)); + } + if (objects->at(id) != NULL) { + JVMCI_ERROR_NULL(err_msg("duplicate virtual object id %d", id)); + } objects->at_put(id, sv); } // All the values which could be referenced by the VirtualObjects // exist, so now describe all the VirtualObjects themselves. for (int i = 0; i < virtualObjects->length(); i++) { - oop value = virtualObjects->obj_at(i); + Handle value = virtualObjects->obj_at(i); int id = VirtualObject::id(value); - record_object_value(objects->at(id)->as_ObjectValue(), value, objects); + record_object_value(objects->at(id)->as_ObjectValue(), value, objects, CHECK_NULL); } _debug_recorder->dump_object_pool(objects); return objects; } -void CodeInstaller::record_scope(jint pc_offset, oop debug_info) { - oop position = DebugInfo::bytecodePosition(debug_info); - if (position == NULL) { +void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, TRAPS) { + Handle position = DebugInfo::bytecodePosition(debug_info); + if (position.is_null()) { // Stubs do not record scope info, just oop maps return; } - GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info); - record_scope(pc_offset, position, objectMapping); + GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info, CHECK); + record_scope(pc_offset, position, objectMapping, CHECK); } -void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) { - oop frame = NULL; +void CodeInstaller::record_scope(jint pc_offset, Handle position, GrowableArray<ScopeValue*>* objects, TRAPS) { + Handle frame; if (position->is_a(BytecodeFrame::klass())) { frame = position; } - oop caller_frame = BytecodePosition::caller(position); - if (caller_frame != NULL) { - record_scope(pc_offset, caller_frame, objects); + Handle caller_frame = BytecodePosition::caller(position); + if (caller_frame.not_null()) { + record_scope(pc_offset, caller_frame, objects, CHECK); } - oop hotspot_method = BytecodePosition::method(position); - Method* method = getMethodFromHotSpotMethod(hotspot_method); + Handle hotspot_method = BytecodePosition::method(position); + Method* method = getMethodFromHotSpotMethod(hotspot_method()); jint bci = BytecodePosition::bci(position); if (bci == BytecodeFrame::BEFORE_BCI()) { bci = SynchronizationEntryBCI; @@ -756,13 +803,13 @@ TRACE_jvmci_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string()); bool reexecute = false; - if (frame != NULL) { + if (frame.not_null()) { if (bci == SynchronizationEntryBCI){ reexecute = false; } else { Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci)); reexecute = bytecode_should_reexecute(code); - if (frame != NULL) { + if (frame.not_null()) { reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE); } } @@ -773,15 +820,19 @@ DebugToken* monitors_token = NULL; bool throw_exception = false; - if (frame != NULL) { + if (frame.not_null()) { jint local_count = BytecodeFrame::numLocals(frame); jint expression_count = BytecodeFrame::numStack(frame); jint monitor_count = BytecodeFrame::numLocks(frame); - objArrayOop values = BytecodeFrame::values(frame); - objArrayOop slotKinds = BytecodeFrame::slotKinds(frame); + objArrayHandle values = BytecodeFrame::values(frame); + objArrayHandle slotKinds = BytecodeFrame::slotKinds(frame); - assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); - assert(local_count + expression_count == slotKinds->length(), "unexpected slotKinds length"); + if (local_count + expression_count + monitor_count != values->length()) { + JVMCI_ERROR(err_msg("unexpected values length %d in scope (%d locals, %d expressions, %d monitors)", values->length(), local_count, expression_count, monitor_count)); + } + if (local_count + expression_count != slotKinds->length()) { + JVMCI_ERROR(err_msg("unexpected slotKinds length %d in scope (%d locals, %d expressions)", slotKinds->length(), local_count, expression_count)); + } GrowableArray<ScopeValue*>* locals = local_count > 0 ? new GrowableArray<ScopeValue*> (local_count) : NULL; GrowableArray<ScopeValue*>* expressions = expression_count > 0 ? new GrowableArray<ScopeValue*> (expression_count) : NULL; @@ -792,30 +843,30 @@ for (jint i = 0; i < values->length(); i++) { ScopeValue* second = NULL; - oop value = values->obj_at(i); + Handle value = values->obj_at(i); if (i < local_count) { - oop kind = slotKinds->obj_at(i); - BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind)); - ScopeValue* first = get_scope_value(value, type, objects, second); + BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(slotKinds->obj_at(i))); + ScopeValue* first = get_scope_value(value, type, objects, second, CHECK); if (second != NULL) { locals->append(second); } locals->append(first); } else if (i < local_count + expression_count) { - oop kind = slotKinds->obj_at(i); - BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind)); - ScopeValue* first = get_scope_value(value, type, objects, second); + BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(slotKinds->obj_at(i))); + ScopeValue* first = get_scope_value(value, type, objects, second, CHECK); if (second != NULL) { expressions->append(second); } expressions->append(first); } else { - monitors->append(get_monitor_value(value, objects)); + MonitorValue *monitor = get_monitor_value(value, objects, CHECK); + monitors->append(monitor); } if (second != NULL) { i++; - assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL"); - assert(values->obj_at(i) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); + if (i >= values->length() || values->obj_at(i) != Value::ILLEGAL()) { + JVMCI_ERROR("double-slot value not followed by Value.ILLEGAL"); + } } } @@ -830,32 +881,37 @@ locals_token, expressions_token, monitors_token); } -void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { - oop debug_info = CompilationResult_Infopoint::debugInfo(site); - assert(debug_info != NULL, "debug info expected"); +void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { + Handle debug_info = CompilationResult_Infopoint::debugInfo(site); + if (debug_info.is_null()) { + JVMCI_ERROR(err_msg("debug info expected at safepoint at %i", pc_offset)); + } // address instruction = _instructions->start() + pc_offset; // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); - _debug_recorder->add_safepoint(pc_offset, create_oop_map(debug_info)); - record_scope(pc_offset, debug_info); + OopMap *map = create_oop_map(debug_info, CHECK); + _debug_recorder->add_safepoint(pc_offset, map); + record_scope(pc_offset, debug_info, CHECK); _debug_recorder->end_safepoint(pc_offset); } -void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site) { - oop debug_info = CompilationResult_Infopoint::debugInfo(site); - assert(debug_info != NULL, "debug info expected"); +void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { + Handle debug_info = CompilationResult_Infopoint::debugInfo(site); + if (debug_info.is_null()) { + JVMCI_ERROR(err_msg("debug info expected at infopoint at %i", pc_offset)); + } _debug_recorder->add_non_safepoint(pc_offset); - record_scope(pc_offset, debug_info); + record_scope(pc_offset, debug_info, CHECK); _debug_recorder->end_non_safepoint(pc_offset); } -void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { - oop target = CompilationResult_Call::target(site); +void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { + Handle target = CompilationResult_Call::target(site); InstanceKlass* target_klass = InstanceKlass::cast(target->klass()); - oop hotspot_method = NULL; // JavaMethod - oop foreign_call = NULL; + Handle hotspot_method; // JavaMethod + Handle foreign_call; if (target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) { foreign_call = target; @@ -863,27 +919,29 @@ hotspot_method = target; } - oop debug_info = CompilationResult_Call::debugInfo(site); + Handle debug_info = CompilationResult_Call::debugInfo(site); - assert(!!hotspot_method ^ !!foreign_call, "Call site needs exactly one type"); + assert(hotspot_method.not_null() ^ foreign_call.not_null(), "Call site needs exactly one type"); NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); - jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); + jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, CHECK); - if (debug_info != NULL) { - _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(debug_info)); - record_scope(next_pc_offset, debug_info); + if (debug_info.not_null()) { + OopMap *map = create_oop_map(debug_info, CHECK); + _debug_recorder->add_safepoint(next_pc_offset, map); + record_scope(next_pc_offset, debug_info, CHECK); } - if (foreign_call != NULL) { + if (foreign_call.not_null()) { jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call); - CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination); + CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK); } else { // method != NULL - assert(hotspot_method != NULL, "unexpected JavaMethod"); - assert(debug_info != NULL, "debug info expected"); + if (debug_info.is_null()) { + JVMCI_ERROR(err_msg("debug info expected at call at %i", pc_offset)); + } TRACE_jvmci_3("method call"); - CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); + CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset, CHECK); if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) { // Need a static call stub for transitions from compiled to interpreted. CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); @@ -892,36 +950,42 @@ _next_call_type = INVOKE_INVALID; - if (debug_info != NULL) { + if (debug_info.not_null()) { _debug_recorder->end_safepoint(next_pc_offset); } } -void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { - oop reference = CompilationResult_DataPatch::reference(site); +void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { + Handle reference = CompilationResult_DataPatch::reference(site); if (reference->is_a(CompilationResult_ConstantReference::klass())) { Handle constant = CompilationResult_ConstantReference::constant(reference); if (constant->is_a(HotSpotObjectConstantImpl::klass())) { - pd_patch_OopConstant(pc_offset, constant); + pd_patch_OopConstant(pc_offset, constant, CHECK); } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { - pd_patch_MetaspaceConstant(pc_offset, constant); + pd_patch_MetaspaceConstant(pc_offset, constant, CHECK); } else { - fatal("unknown constant type in data patch"); + JVMCI_ERROR(err_msg("unknown constant type in data patch: %s", constant->klass()->signature_name())); } } else if (reference->is_a(CompilationResult_DataSectionReference::klass())) { int data_offset = CompilationResult_DataSectionReference::offset(reference); - assert(0 <= data_offset && data_offset < _constants_size, err_msg("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size)); + if (0 <= data_offset && data_offset < _constants_size) { + pd_patch_DataSectionReference(pc_offset, data_offset); + } else { + JVMCI_ERROR(err_msg("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size)); + } pd_patch_DataSectionReference(pc_offset, data_offset); } else { - fatal("unknown data patch type"); + JVMCI_ERROR(err_msg("unknown data patch type: %s", reference->klass()->signature_name())); } } -void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { - oop id_obj = CompilationResult_Mark::id(site); +void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { + Handle id_obj = CompilationResult_Mark::id(site); - if (id_obj != NULL) { - assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); + if (id_obj.not_null()) { + if (!java_lang_boxing_object::is_instance(id_obj(), T_INT)) { + JVMCI_ERROR(err_msg("expected Integer id, got %s", id_obj->klass()->signature_name())); + } jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); address pc = _instructions->start() + pc_offset; @@ -954,13 +1018,13 @@ case POLL_FAR: case POLL_RETURN_NEAR: case POLL_RETURN_FAR: - pd_relocate_poll(pc, id); + pd_relocate_poll(pc, id, CHECK); break; case CARD_TABLE_SHIFT: case CARD_TABLE_ADDRESS: break; default: - ShouldNotReachHere(); + JVMCI_ERROR(err_msg("invalid mark id: %d", id)); break; } }