# HG changeset patch # User Lukas Stadler # Date 1282253692 25200 # Node ID 695451afc619e2d37ccbf3d6f77f83609d33b8ca # Parent 149b1d2316de155a7cc1f1e6234b880ae1181cf6 refactoring classes into separate files diff -r 149b1d2316de -r 695451afc619 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Wed Aug 18 16:47:06 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Thu Aug 19 14:34:52 2010 -0700 @@ -46,6 +46,7 @@ public long debugStub; public long resolveStaticCallStub; public long newInstanceStub; + public long throwImplicitNullStub; public void check() { assert vmPageSize >= 16; diff -r 149b1d2316de -r 695451afc619 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Wed Aug 18 16:47:06 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Thu Aug 19 14:34:52 2010 -0700 @@ -35,17 +35,17 @@ */ public class HotSpotXirGenerator implements RiXirGenerator { - // this needs to correspond to c1x_Compiler.hpp - private static final Integer MARK_VERIFIED_ENTRY = 1; - private static final Integer MARK_UNVERIFIED_ENTRY = 2; - private static final Integer MARK_OSR_ENTRY = 3; - private static final Integer MARK_STATIC_CALL_STUB = 1000; - - private static final Integer MARK_INVOKE_INVALID = 2000; - private static final Integer MARK_INVOKEINTERFACE = 2001; - private static final Integer MARK_INVOKESTATIC = 2002; - private static final Integer MARK_INVOKESPECIAL = 2003; - private static final Integer MARK_INVOKEVIRTUAL = 2004; + // this needs to correspond to c1x_CodeInstaller.hpp + private static final Integer MARK_VERIFIED_ENTRY = 0x0001; + private static final Integer MARK_UNVERIFIED_ENTRY = 0x0002; + private static final Integer MARK_OSR_ENTRY = 0x0003; + private static final Integer MARK_STATIC_CALL_STUB = 0x1000; + private static final Integer MARK_INVOKE_INVALID = 0x2000; + private static final Integer MARK_INVOKEINTERFACE = 0x2001; + private static final Integer MARK_INVOKESTATIC = 0x2002; + private static final Integer MARK_INVOKESPECIAL = 0x2003; + private static final Integer MARK_INVOKEVIRTUAL = 0x2004; + private static final Integer MARK_IMPLICIT_NULL_EXCEPTION_TARGET = 0x3000; private final HotSpotVMConfig config; private final CiTarget target; @@ -447,6 +447,9 @@ asm.jmp(dummy); asm.bindOutOfLine(dummy); + asm.mark(MARK_IMPLICIT_NULL_EXCEPTION_TARGET, XirMark.CALLSITE); + asm.callRuntime(config.throwImplicitNullStub, null); + return asm.finishTemplate(addr, "invokespecial"); } diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_CodeInstaller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_CodeInstaller.cpp Thu Aug 19 14:34:52 2010 -0700 @@ -0,0 +1,528 @@ +/* + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +# include "incls/_precompiled.incl" +# include "incls/_c1x_CodeInstaller.cpp.incl" + + +#define C1X_REGISTER_COUNT 32 + +VMReg get_hotspot_reg(jint c1x_reg) { + Register cpu_registers[] = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15 }; + XMMRegister xmm_registers[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 }; + + if (c1x_reg < 16) { + return cpu_registers[c1x_reg]->as_VMReg(); + } else { + assert(c1x_reg < C1X_REGISTER_COUNT, "invalid register number"); + return xmm_registers[c1x_reg - 16]->as_VMReg(); + } + +} + +static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) { + OopMap* map = new OopMap(frame_size, parameter_count); + arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info); + arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info); + + for (jint i=0; ibase(T_BYTE))[i / 8]; + bool is_oop = (byte & (1 << (i % 8))) != 0; + VMReg reg = get_hotspot_reg(i); + if (is_oop) { + map->set_oop(reg); + } else { + map->set_value(reg); + } + } + + for (jint i=0; ibase(T_BYTE))[i / 8]; + bool is_oop = (byte & (1 << (i % 8))) != 0; + VMReg reg = VMRegImpl::stack2reg(i); + if (is_oop) { + map->set_oop(reg); + } else { + map->set_value(reg); + } + } + + // TODO parameters? + return map; +} + +static ScopeValue* get_hotspot_value(oop value) { + fatal("not implemented"); + if (value->is_a(CiRegisterValue::klass())) { + tty->print("register value"); + value->print(); + } else if (value->is_a(CiStackSlot::klass())) { + tty->print("stack value"); + value->print(); + } else { + ShouldNotReachHere(); + } +} + + +// constructor used to create a method +CodeInstaller::CodeInstaller(oop target_method) { + VM_ENTRY_MARK; + _env = CURRENT_ENV; + + initialize_fields(target_method); + assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name"); + + + // TODO: This is a hack.. Produce correct entries. + _offsets.set_value(CodeOffsets::Exceptions, 0); + _offsets.set_value(CodeOffsets::Deopt, 0); + + methodOop method = VmIds::get(HotSpotMethod::vmId(_hotspot_method)); + ciMethod *ciMethodObject = (ciMethod *)_env->get_object(method); + _parameter_count = method->size_of_parameters(); + + // (very) conservative estimate: each site needs a relocation + CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit); + initialize_buffer(buffer); + ExceptionHandlerTable handler_table; + ImplicitExceptionTable inc_table; + { + ThreadToNativeFromVM t((JavaThread*)THREAD); + _env->register_method(ciMethodObject, -1, &_offsets, 0, &buffer, _frame_size, _debug_recorder->_oopmaps, &handler_table, &inc_table, NULL, _env->comp_level(), false, false); + } +} + +// constructor used to create a stub +CodeInstaller::CodeInstaller(oop target_method, jlong& id) { + VM_ENTRY_MARK; + _env = CURRENT_ENV; + + initialize_fields(target_method); + assert(_hotspot_method == NULL && _name != NULL, "installMethod needs NON-NULL name and NULL method"); + + // (very) conservative estimate: each site needs a relocation + CodeBuffer buffer("temp c1x stub", _total_size, _sites->length() * relocInfo::length_limit); + initialize_buffer(buffer); + + const char* cname = java_lang_String::as_utf8_string(_name); + BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created + Disassembler::decode((CodeBlob*)blob); + id = VmIds::addStub(blob->instructions_begin()); +} + +void CodeInstaller::initialize_fields(oop target_method) { + _citarget_method = HotSpotTargetMethod::targetMethod(target_method); + _hotspot_method = HotSpotTargetMethod::method(target_method); + _name = HotSpotTargetMethod::name(target_method); + _sites = (arrayOop)HotSpotTargetMethod::sites(target_method); + + _code = (arrayOop)CiTargetMethod::targetCode(_citarget_method); + _code_size = CiTargetMethod::targetCodeSize(_citarget_method); + _frame_size = CiTargetMethod::frameSize(_citarget_method); + + // (very) conservative estimate: each site needs a constant section entry + _constants_size = _sites->length() * BytesPerLong; + _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size; + + _next_call_type = MARK_INVOKE_INVALID; +} + +void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { + +} + +void CodeInstaller::record_frame(jint pc_offset, oop code_pos, oop frame) { + oop caller_pos = CiCodePos::caller(code_pos); + if (caller_pos != NULL) { + oop caller_frame = CiDebugInfo_Frame::caller(frame); + record_frame(pc_offset, caller_pos, caller_frame); + } else { + assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - different nesting of Frame and CiCodePos"); + } + + assert(frame == NULL || code_pos == CiDebugInfo_Frame::codePos(frame), "unexpected CiCodePos layout"); + + oop hotspot_method = CiCodePos::method(code_pos); + methodOop method = VmIds::get(HotSpotMethod::vmId(hotspot_method)); + ciMethod *cimethod = (ciMethod *)_env->get_object(method); + jint bci = CiCodePos::bci(code_pos); + + if (frame != NULL) { + jint local_count = CiDebugInfo_Frame::numLocals(frame); + jint expression_count = CiDebugInfo_Frame::numStack(frame); + jint monitor_count = CiDebugInfo_Frame::numLocks(frame); + arrayOop values = (arrayOop)CiDebugInfo_Frame::values(frame); + + assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); + assert(monitor_count == 0, "monitors not supported"); + + GrowableArray* locals = new GrowableArray(); + GrowableArray* expressions = new GrowableArray(); + GrowableArray* monitors = new GrowableArray(); + + for (jint i=0; ilength(); i++) { + ScopeValue* value = get_hotspot_value(((oop*)values->base(T_OBJECT))[i]); + + if (i < local_count) { + locals->append(value); + } else if (i < local_count + expression_count) { + expressions->append(value); + } else { + ShouldNotReachHere(); + // monitors->append(value); + } + } + DebugToken* locals_token = _debug_recorder->create_scope_values(locals); + DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); + DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); + + _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, locals_token, expressions_token, monitors_token); + } else { + _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, NULL, NULL, NULL); + } +} + +void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { + oop runtime_call = CiTargetMethod_Call::runtimeCall(site); + oop hotspot_method = CiTargetMethod_Call::method(site); + oop symbol = CiTargetMethod_Call::symbol(site); + oop global_stub = CiTargetMethod_Call::globalStubID(site); + + oop debug_info = CiTargetMethod_Call::debugInfo(site); + arrayOop stack_map = (arrayOop)CiTargetMethod_Call::stackMap(site); + arrayOop register_map = (arrayOop)CiTargetMethod_Call::registerMap(site); + + assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); + + address instruction = _instructions->start() + pc_offset; + address operand = Assembler::locate_operand(instruction, Assembler::call32_operand); + address next_instruction = Assembler::locate_next_instruction(instruction); + + if (runtime_call != NULL) { + if (runtime_call == CiRuntimeCall::Debug()) { + tty->print_cr("CiRuntimeCall::Debug()"); + } else { + runtime_call->print(); + } + tty->print_cr("runtime_call"); + } else if (global_stub != NULL) { + assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long"); + + jlong stub_id = global_stub->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); + address dest = VmIds::getStub(stub_id); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; + + _instructions->relocate(instruction, runtime_call_Relocation::spec(), Assembler::call32_operand); + tty->print_cr("relocating (stub) %016x/%016x", instruction, operand); + } else if (symbol != NULL) { + tty->print_cr("symbol"); + } else { // method != NULL + assert(hotspot_method->is_a(SystemDictionary::HotSpotMethod_klass()), "unexpected RiMethod subclass"); + methodOop method = VmIds::get(HotSpotMethod::vmId(hotspot_method)); + + jint next_pc_offset = next_instruction - _instructions->start(); + + assert(debug_info != NULL, "debug info expected"); + _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); + oop code_pos = CiDebugInfo::codePos(debug_info); + oop frame = CiDebugInfo::frame(debug_info); + record_frame(next_pc_offset, code_pos, frame); + + switch(_next_call_type) { + case MARK_INVOKEVIRTUAL: + case MARK_INVOKEINTERFACE: { + assert(!method->is_static(), "cannot call static method with invokeinterface"); + + address dest = SharedRuntime::get_resolve_virtual_call_stub(); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; + + _instructions->relocate(instruction, virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); + break; + } + case MARK_INVOKESTATIC: { + assert(method->is_static(), "cannot call non-static method with invokestatic"); + + address dest = SharedRuntime::get_resolve_static_call_stub(); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; + + _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand); + break; + } + case MARK_INVOKESPECIAL: { + assert(!method->is_static(), "cannot call static method with invokespecial"); + + address dest = SharedRuntime::get_resolve_opt_virtual_call_stub(); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; + + _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand); + break; + } + case MARK_INVOKE_INVALID: + default: + ShouldNotReachHere(); + break; + } + _next_call_type = MARK_INVOKE_INVALID; + _debug_recorder->end_safepoint(pc_offset); + } +} + +void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { + oop constant = CiTargetMethod_DataPatch::constant(site); + oop kind = CiConstant::kind(constant); + + address instruction = _instructions->start() + pc_offset; + + switch(CiKind::typeChar(kind)) { + case 'z': + case 'b': + case 's': + case 'c': + case 'i': + fatal("int-sized values not expected in DataPatch"); + break; + case 'f': + case 'l': + case 'd': { + address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(instruction); + // we don't care if this is a long/double/etc., the primitive field contains the right bits + address dest = _constants->end(); + *(jlong*)dest = CiConstant::primitive(constant); + _constants->set_end(dest + BytesPerLong); + + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; + + _instructions->relocate(instruction, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + tty->print_cr("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); + break; + } + case 'a': { + address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + oop obj = CiConstant::object(constant); + + if (obj->is_a(HotSpotTypeResolved::klass())) { + *((jobject*)operand) = JNIHandles::make_local(VmIds::get(HotSpotTypeResolved::vmId(obj))); + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + tty->print_cr("relocating (HotSpotType) at %016x/%016x", instruction, operand); + } else { + assert(java_lang_boxing_object::is_instance(obj, T_LONG), "unexpected DataPatch object type"); + jlong id = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); + + assert((id & VmIds::TYPE_MASK) == VmIds::CONSTANT, "unexpected DataPatch type"); + + address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + + if (id == VmIds::DUMMY_CONSTANT) { + *((jobject*)operand) = (jobject)Universe::non_oop_word(); + } else { + *((jobject*)operand) = JNIHandles::make_local(VmIds::get(id)); + } + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + tty->print_cr("relocating (oop constant) at %016x/%016x", instruction, operand); + } + break; + } + default: + fatal("unexpected CiKind in DataPatch"); + break; + } +} + +void CodeInstaller::site_ExceptionHandler(CodeBuffer& buffer, jint pc_offset, oop site) { + +} + +void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { + oop id_obj = CiTargetMethod_Mark::id(site); + arrayOop references = (arrayOop)CiTargetMethod_Mark::references(site); + + if (id_obj != NULL) { + assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); + jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); + + address instruction = _instructions->start() + pc_offset; + + switch (id) { + case MARK_UNVERIFIED_ENTRY: + _offsets.set_value(CodeOffsets::Entry, pc_offset); + break; + case MARK_VERIFIED_ENTRY: + _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); + break; + case MARK_OSR_ENTRY: + _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); + break; + case MARK_STATIC_CALL_STUB: { + assert(references->length() == 1, "static call stub needs one reference"); + oop ref = ((oop*)references->base(T_OBJECT))[0]; + address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref); + _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); + break; + } + case MARK_INVOKE_INVALID: + case MARK_INVOKEINTERFACE: + case MARK_INVOKESTATIC: + case MARK_INVOKESPECIAL: + case MARK_INVOKEVIRTUAL: + _next_call_type = (MarkId)id; + _invoke_mark_pc = instruction; + break; + case MARK_IMPLICIT_NULL_EXCEPTION_TARGET: + break; + default: + ShouldNotReachHere(); + break; + } + } +} + +// perform data and call relocation on the CodeBuffer +void CodeInstaller::initialize_buffer(CodeBuffer& buffer) { + _oop_recorder = new OopRecorder(_env->arena()); + _env->set_oop_recorder(_oop_recorder); + _debug_recorder = new DebugInformationRecorder(_env->oop_recorder()); + _debug_recorder->set_oopmaps(new OopMapSet()); + _dependencies = new Dependencies(_env); + + _env->set_oop_recorder(_oop_recorder); + _env->set_debug_info(_debug_recorder); + _env->set_dependencies(_dependencies); + buffer.initialize_oop_recorder(_oop_recorder); + + buffer.initialize_consts_size(_constants_size); + _instructions = buffer.insts(); + _constants = buffer.consts(); + + // copy the code into the newly created CodeBuffer + memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); + _instructions->set_end(_instructions->start() + _code_size); + + oop* sites = (oop*)_sites->base(T_OBJECT); + for (int i=0; i<_sites->length(); i++) { + oop site = sites[i]; + jint pc_offset = CiTargetMethod_Site::pcOffset(site); + + if (site->is_a(CiTargetMethod_Safepoint::klass())) { + tty->print_cr("safepoint at %i", pc_offset); + site_Safepoint(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_Call::klass())) { + tty->print_cr("call at %i", pc_offset); + site_Call(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_DataPatch::klass())) { + tty->print_cr("datapatch at %i", pc_offset); + site_DataPatch(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_ExceptionHandler::klass())) { + tty->print_cr("exception handler at %i", pc_offset); + site_ExceptionHandler(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_Mark::klass())) { + tty->print_cr("mark at %i", pc_offset); + site_Mark(buffer, pc_offset, site); + } else { + ShouldNotReachHere(); + } + } + +/* + if (_relocation_count > 0) { + jint* relocation_offsets = (jint*)((arrayOop)JNIHandles::resolve(_relocation_offsets))->base(T_INT); + oop* relocation_objects = (oop*)((arrayOop)JNIHandles::resolve(_relocation_data))->base(T_OBJECT); + + for (int i = 0; i < _relocation_count; i++) { + address inst = (address)instructions->start() + relocation_offsets[i]; + u_char inst_byte = *inst; + oop obj = relocation_objects[i]; + assert(obj != NULL, "NULL oop needn't be patched"); + + if (obj->is_a(SystemDictionary::HotSpotProxy_klass())) { + jlong id = com_sun_hotspot_c1x_HotSpotProxy::get_id(obj); + switch (id & VmIds::TYPE_MASK) { + case VmIds::CONSTANT: { + address operand = Assembler::locate_operand(inst, Assembler::imm_operand); + + *((jobject*)operand) = JNIHandles::make_local(VmIds::get(id)); + instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); + break; + } + case VmIds::STUB: { + address operand = Assembler::locate_operand(inst, Assembler::call32_operand); + + long dest = (long)VmIds::getStub(id); + long disp = dest - (long)(operand + 4); + assert(disp == (int) disp, "disp doesn't fit in 32 bits"); + *((int*)operand) = (int)disp; + + instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand); + break; + } + } + } else if (java_lang_boxing_object::is_instance(obj)) { + address operand = Assembler::locate_operand(inst, Assembler::disp32_operand); + long dest = (long)constants->end(); + if (java_lang_boxing_object::is_instance(obj, T_LONG)) { + // tty->print("relocate: %l\n", obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG))); + *(jlong*)constants->end() = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); + } else if (java_lang_boxing_object::is_instance(obj, T_DOUBLE)) { + // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); + *(jdouble*)constants->end() = obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE)); + } else if (java_lang_boxing_object::is_instance(obj, T_FLOAT)) { + // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); + *(jfloat*)constants->end() = obj->float_field(java_lang_boxing_object::value_offset_in_bytes(T_FLOAT)); + } + constants->set_end(constants->end() + 8); + + long disp = dest - (long)(operand + 4); + assert(disp == (int) disp, "disp doesn't fit in 32 bits"); + *((int*)operand) = (int)disp; + + instructions->relocate(inst, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + tty->print_cr("relocating (Long/Double) %02x at %016x/%016x", inst_byte, inst, operand); + } else if (obj->is_a(_types.HotSpotTypeResolved)) { + address operand = Assembler::locate_operand(inst, Assembler::imm_operand); + + *((jobject*)operand) = JNIHandles::make_local(VmIds::get(obj->obj_field(_types.HotSpotTypeResolved_klassOop))); + instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); + } else { + tty->print_cr("unknown relocation type"); + obj->print(); + } + } + }*/ +} + diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_CodeInstaller.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_CodeInstaller.hpp Thu Aug 19 14:34:52 2010 -0700 @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class CodeInstaller { +private: + // this needs to correspond to HotSpotXirGenerator.java + enum MarkId { + MARK_VERIFIED_ENTRY = 0x0001, + MARK_UNVERIFIED_ENTRY = 0x0002, + MARK_OSR_ENTRY = 0x0003, + MARK_STATIC_CALL_STUB = 0x1000, + MARK_INVOKE_INVALID = 0x2000, + MARK_INVOKEINTERFACE = 0x2001, + MARK_INVOKESTATIC = 0x2002, + MARK_INVOKESPECIAL = 0x2003, + MARK_INVOKEVIRTUAL = 0x2004, + MARK_IMPLICIT_NULL_EXCEPTION_TARGET = 0x3000 + }; + + ciEnv* _env; + + oop _citarget_method; + oop _hotspot_method; + oop _name; + arrayOop _sites; + CodeOffsets _offsets; + + arrayOop _code; + jint _code_size; + jint _frame_size; + jint _parameter_count; + jint _constants_size; + jint _total_size; + + MarkId _next_call_type; + address _invoke_mark_pc; + + CodeSection* _instructions; + CodeSection* _constants; + + OopRecorder* _oop_recorder; + DebugInformationRecorder* _debug_recorder; + Dependencies* _dependencies; + +public: + + // constructor used to create a method + CodeInstaller(oop target_method); + + // constructor used to create a stub + CodeInstaller(oop target_method, jlong& id); + +private: + void initialize_fields(oop target_method); + + // perform data and call relocation on the CodeBuffer + void initialize_buffer(CodeBuffer& buffer); + + void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site); + void site_Call(CodeBuffer& buffer, jint pc_offset, oop site); + void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); + void site_ExceptionHandler(CodeBuffer& buffer, jint pc_offset, oop site); + void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); + + void record_frame(jint pc_offset, oop code_pos, oop frame); + +}; diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_Compiler.cpp --- a/src/share/vm/c1x/c1x_Compiler.cpp Wed Aug 18 16:47:06 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.cpp Thu Aug 19 14:34:52 2010 -0700 @@ -40,7 +40,7 @@ check_pending_exception("Could not register natives"); - compute_offsets(); + c1x_compute_offsets(); } // Compilation entry point for methods @@ -48,18 +48,17 @@ initialize(); VM_ENTRY_MARK; - ResourceMark rm; HandleMark hm; - C1XObjects::initializeObjects(); + VmIds::initializeObjects(); CompilerThread::current()->set_compiling(true); methodOop method = (methodOop)target->get_oop(); - VMExits::compileMethod(C1XObjects::add(method), C1XObjects::toString(method->name(), THREAD), entry_bci); + VMExits::compileMethod(VmIds::add(method), VmIds::toString(method->name(), THREAD), entry_bci); CompilerThread::current()->set_compiling(false); - C1XObjects::cleanupLocalObjects(); + VmIds::cleanupLocalObjects(); } // Print compilation timers and statistics @@ -73,124 +72,20 @@ return VMExits::createRiTypePrimitive((int)type->basic_type(), THREAD); } klassOop klass = (klassOop)type->get_oop(); - return VMExits::createRiType(C1XObjects::add(klass), C1XObjects::toString(klass->klass_part()->name(), THREAD), THREAD); + return VMExits::createRiType(VmIds::add(klass), VmIds::toString(klass->klass_part()->name(), THREAD), THREAD); } else { symbolOop name = ((ciKlass *)type)->name()->get_symbolOop(); - return VMExits::createRiTypeUnresolved(C1XObjects::toString(name, THREAD), C1XObjects::add(accessor), THREAD); + return VMExits::createRiTypeUnresolved(VmIds::toString(name, THREAD), VmIds::add(accessor), THREAD); } } oop C1XCompiler::get_RiField(ciField *field, TRAPS) { oop field_holder = get_RiType(field->holder(), NULL, CHECK_0); oop field_type = get_RiType(field->type(), NULL, CHECK_0); - Handle field_name = C1XObjects::toString(field->name()->get_symbolOop(), CHECK_0); + Handle field_name = VmIds::toString(field->name()->get_symbolOop(), CHECK_0); int offset = field->offset(); // TODO: implement caching return VMExits::createRiField(field_holder, field_name, field_type, offset, THREAD); } -// C1XObjects implementation - -GrowableArray
* C1XObjects::_stubs = NULL; -GrowableArray* C1XObjects::_localHandles = NULL; - -void C1XObjects::initializeObjects() { - if (_stubs == NULL) { - assert(_localHandles == NULL, "inconsistent state"); - _stubs = new(ResourceObj::C_HEAP) GrowableArray
(64, true); - _localHandles = new(ResourceObj::C_HEAP) GrowableArray(64, true); - } - assert(_localHandles->length() == 0, "invalid state"); -} - -void C1XObjects::cleanupLocalObjects() { - for (int i=0; i<_localHandles->length(); i++) { - JNIHandles::destroy_global(_localHandles->at(i)); - } - _localHandles->clear(); -} - -jlong C1XObjects::addStub(address stub) { - assert(!_stubs->contains(stub), "duplicate stub"); - return _stubs->append(stub) | STUB; -} - -jlong C1XObjects::add(Handle obj, CompilerObjectType type) { - assert(!obj.is_null(), "cannot add NULL handle"); - int idx = -1; - for (int i=0; i<_localHandles->length(); i++) - if (JNIHandles::resolve_non_null(_localHandles->at(i)) == obj()) { - idx = i; - break; - } - if (idx = -1) { - if (JavaThread::current()->thread_state() == _thread_in_vm) { - idx = _localHandles->append(JNIHandles::make_global(obj)); - } else { - VM_ENTRY_MARK; - idx = _localHandles->append(JNIHandles::make_global(obj)); - } - } - return idx | type; -} - -address C1XObjects::getStub(jlong id) { - assert((id & TYPE_MASK) == STUB, "wrong id type, STUB expected"); - assert((id & ~TYPE_MASK) >= 0 && (id & ~TYPE_MASK) < _stubs->length(), "STUB index out of bounds"); - return _stubs->at(id & ~TYPE_MASK); -} - -oop C1XObjects::getObject(jlong id) { - assert((id & TYPE_MASK) != STUB, "wrong id type"); - assert((id & ~TYPE_MASK) >= 0 && (id & ~TYPE_MASK) < _localHandles->length(), "index out of bounds"); - return JNIHandles::resolve_non_null(_localHandles->at(id & ~TYPE_MASK)); -} - - -static void compute_offset(int &dest_offset, klassOop klass_oop, const char* name, const char* signature, bool static_field) { - symbolOop name_symbol = SymbolTable::probe(name, strlen(name)); - symbolOop signature_symbol = SymbolTable::probe(signature, strlen(signature)); - assert(name_symbol != NULL, "symbol not found - class layout changed?"); - assert(signature_symbol != NULL, "symbol not found - class layout changed?"); - - instanceKlass* ik = instanceKlass::cast(klass_oop); - fieldDescriptor fd; - if (!ik->find_field(name_symbol, signature_symbol, &fd)) { - ResourceMark rm; - tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string()); - fatal("Invalid layout of preloaded class"); - } - assert(fd.is_static() == static_field, "static/instance mismatch"); - dest_offset = fd.offset(); -} - -// create the compute_class -#define START_CLASS(name) { klassOop k = SystemDictionary::name##_klass(); - -#define END_CLASS } - -#define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field); -#define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false) -#define INT_FIELD(klass, name) FIELD(klass, name, "I", false) -#define LONG_FIELD(klass, name) FIELD(klass, name, "J", false) -#define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false) -#define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true) - - -void C1XCompiler::compute_offsets() { - COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) -} - -#define EMPTY0 -#define EMPTY1(x) -#define EMPTY2(x,y) -#define FIELD2(klass, name) int klass::_##name##_offset = 0; -#define FIELD3(klass, name, sig) FIELD2(klass, name) - -COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3) - - - - - diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_Compiler.hpp --- a/src/share/vm/c1x/c1x_Compiler.hpp Wed Aug 18 16:47:06 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.hpp Thu Aug 19 14:34:52 2010 -0700 @@ -54,21 +54,6 @@ static oop get_RiType(ciType *klass, klassOop accessor, TRAPS); static oop get_RiField(ciField *ciField, TRAPS); - static void compute_offsets(); - - // this needs to correspond to HotSpotXirGenerator.java - enum MarkId { - MARK_VERIFIED_ENTRY = 1, - MARK_UNVERIFIED_ENTRY = 2, - MARK_OSR_ENTRY = 3, - MARK_STATIC_CALL_STUB = 1000, - MARK_INVOKE_INVALID = 2000, - MARK_INVOKEINTERFACE = 2001, - MARK_INVOKESTATIC = 2002, - MARK_INVOKESPECIAL = 2003, - MARK_INVOKEVIRTUAL = 2004 - }; - /* static oop get_RiMethod(ciMethod *ciMethod, TRAPS); static oop get_RiType(klassOop klass, TRAPS); @@ -78,105 +63,6 @@ */ }; -class C1XObjects : public AllStatic { - -private: - static GrowableArray
* _stubs; - static GrowableArray* _localHandles; - - static oop getObject(jlong id); - -public: - // this enum needs to have the same values as the one in HotSpotProxy.java - enum CompilerObjectType { - STUB = 0x100000000000000l, - METHOD = 0x200000000000000l, - CLASS = 0x300000000000000l, - SYMBOL = 0x400000000000000l, - CONSTANT_POOL = 0x500000000000000l, - CONSTANT = 0x600000000000000l, - TYPE_MASK = 0xf00000000000000l, - DUMMY_CONSTANT = 0x6ffffffffffffffl - }; - - static void initializeObjects(); - static void cleanupLocalObjects(); - - static jlong addStub(address stub); - static jlong add(Handle obj, CompilerObjectType type); - template static jlong add(T obj); - - static address getStub(jlong id); - template static T get(jlong id); - - template static T toString(symbolOop symbol, TRAPS); - static symbolOop toSymbol(jstring string); -}; - -template <> inline jlong C1XObjects::add(methodOop obj){ - assert(obj != NULL && obj->is_method(), "trying to add NULL or mistyped object"); - return add(Handle(obj), METHOD); -} -template <> inline jlong C1XObjects::add(klassOop obj) { - assert(obj != NULL && obj->is_klass(), "trying to add NULL or mistyped object"); - return add(Handle(obj), CLASS); -} -template <> inline jlong C1XObjects::add(symbolOop obj) { - assert(obj != NULL && obj->is_symbol(), "trying to add NULL or mistyped object"); - return add(Handle(obj), SYMBOL); -} -template <> inline jlong C1XObjects::add(constantPoolOop obj) { - assert(obj != NULL && obj->is_constantPool(), "trying to add NULL or mistyped object"); - return add(Handle(obj), CONSTANT_POOL); -} -template <> inline jlong C1XObjects::add(oop obj) { - assert(obj != NULL && obj->is_oop(), "trying to add NULL or mistyped object"); - return add(Handle(obj), CONSTANT); -} - -template <> inline methodOop C1XObjects::get(jlong id){ - assert((id & TYPE_MASK) == METHOD, "METHOD expected"); - assert(getObject(id)->is_method(), "methodOop expected"); - return (methodOop)getObject(id); -} -template <> inline klassOop C1XObjects::get(jlong id) { - assert((id & TYPE_MASK) == CLASS, "CLASS expected"); - assert(getObject(id)->is_klass(), "klassOop expected"); - return (klassOop)getObject(id); -} -template <> inline symbolOop C1XObjects::get(jlong id) { - assert((id & TYPE_MASK) == SYMBOL, "SYMBOL expected"); - assert(getObject(id)->is_symbol(), "symbolOop expected"); - return (symbolOop)getObject(id); -} -template <> inline constantPoolOop C1XObjects::get(jlong id) { - assert((id & TYPE_MASK) == CONSTANT_POOL, "CONSTANT_POOL expected"); - assert(getObject(id)->is_constantPool(), "constantPoolOop expected"); - return (constantPoolOop)getObject(id); -} -template <> inline oop C1XObjects::get(jlong id) { - assert((id & TYPE_MASK) == CONSTANT, "CONSTANT expected"); - assert(getObject(id)->is_oop(true), "oop expected"); - return (oop)getObject(id); -} - -template <> inline Handle C1XObjects::toString(symbolOop symbol, TRAPS) { - return java_lang_String::create_from_symbol(symbol, THREAD); -} -template <> inline oop C1XObjects::toString(symbolOop symbol, TRAPS) { - return toString(symbol, THREAD)(); -} -template <> inline jstring C1XObjects::toString(symbolOop symbol, TRAPS) { - return (jstring)JNIHandles::make_local(toString(symbol, THREAD)); -} -template <> inline jobject C1XObjects::toString(symbolOop symbol, TRAPS) { - return JNIHandles::make_local(toString(symbol, THREAD)); -} - -inline symbolOop C1XObjects::toSymbol(jstring string) { - return java_lang_String::as_symbol_or_null(JNIHandles::resolve(string)); -} - // Tracing macros #define IF_TRACE_C1X_1 if (TraceC1X >= 1) @@ -192,127 +78,4 @@ #define TRACE_C1X_5 if (TraceC1X >= 5) tty->print(" TraceC1X-5: "); if (TraceC1X >= 5) tty->print_cr -// defines the structure of the CiTargetMethod - classes -// this will generate classes with accessors similar to javaClasses.hpp -#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, long_field, oop_field, static_oop_field) \ - start_class(HotSpotTypeResolved) \ - long_field(HotSpotTypeResolved, vmId) \ - end_class \ - start_class(HotSpotMethod) \ - long_field(HotSpotMethod, vmId) \ - end_class \ - start_class(HotSpotTargetMethod) \ - oop_field(HotSpotTargetMethod, targetMethod, "Lcom/sun/cri/ci/CiTargetMethod;") \ - oop_field(HotSpotTargetMethod, method, "Lcom/sun/hotspot/c1x/HotSpotMethod;") \ - oop_field(HotSpotTargetMethod, name, "Ljava/lang/String;") \ - oop_field(HotSpotTargetMethod, sites, "[Lcom/sun/cri/ci/CiTargetMethod$Site;") \ - end_class \ - start_class(CiTargetMethod) \ - int_field(CiTargetMethod, frameSize) \ - oop_field(CiTargetMethod, targetCode, "[B") \ - int_field(CiTargetMethod, targetCodeSize) \ - int_field(CiTargetMethod, referenceRegisterCount) \ - end_class \ - start_class(CiTargetMethod_Site) \ - int_field(CiTargetMethod_Site, pcOffset) \ - end_class \ - start_class(CiTargetMethod_Call) \ - oop_field(CiTargetMethod_Call, runtimeCall, "Lcom/sun/cri/ci/CiRuntimeCall;") \ - oop_field(CiTargetMethod_Call, method, "Lcom/sun/cri/ri/RiMethod;") \ - oop_field(CiTargetMethod_Call, symbol, "Ljava/lang/String;") \ - oop_field(CiTargetMethod_Call, globalStubID, "Ljava/lang/Object;") \ - oop_field(CiTargetMethod_Call, debugInfo, "Lcom/sun/cri/ci/CiDebugInfo;") \ - oop_field(CiTargetMethod_Call, stackMap, "[B") \ - oop_field(CiTargetMethod_Call, registerMap, "[B") \ - end_class \ - start_class(CiTargetMethod_DataPatch) \ - oop_field(CiTargetMethod_DataPatch, constant, "Lcom/sun/cri/ci/CiConstant;") \ - end_class \ - start_class(CiTargetMethod_Safepoint) \ - oop_field(CiTargetMethod_Safepoint, debugInfo, "Lcom/sun/cri/ci/CiDebugInfo;") \ - end_class \ - start_class(CiTargetMethod_ExceptionHandler) \ - int_field(CiTargetMethod_ExceptionHandler, handlerPos) \ - oop_field(CiTargetMethod_ExceptionHandler, exceptionType, "Lcom/sun/cri/ri/RiType;")\ - end_class \ - start_class(CiTargetMethod_Mark) \ - oop_field(CiTargetMethod_Mark, id, "Ljava/lang/Object;") \ - oop_field(CiTargetMethod_Mark, references, "[Lcom/sun/cri/ci/CiTargetMethod$Mark;") \ - end_class \ - start_class(CiDebugInfo) \ - oop_field(CiDebugInfo, codePos, "Lcom/sun/cri/ci/CiCodePos;") \ - oop_field(CiDebugInfo, frame, "Lcom/sun/cri/ci/CiDebugInfo$Frame;") \ - oop_field(CiDebugInfo, registerRefMap, "[B") \ - oop_field(CiDebugInfo, frameRefMap, "[B") \ - end_class \ - start_class(CiDebugInfo_Frame) \ - oop_field(CiDebugInfo_Frame, caller, "Lcom/sun/cri/ci/CiDebugInfo$Frame;") \ - oop_field(CiDebugInfo_Frame, codePos, "Lcom/sun/cri/ci/CiCodePos;") \ - oop_field(CiDebugInfo_Frame, values, "[Lcom/sun/cri/ci/CiValue;") \ - int_field(CiDebugInfo_Frame, numLocals) \ - int_field(CiDebugInfo_Frame, numStack) \ - int_field(CiDebugInfo_Frame, numLocks) \ - end_class \ - start_class(CiCodePos) \ - oop_field(CiCodePos, caller, "Lcom/sun/cri/ci/CiCodePos;") \ - oop_field(CiCodePos, method, "Lcom/sun/cri/ri/RiMethod;") \ - int_field(CiCodePos, bci) \ - end_class \ - start_class(CiConstant) \ - oop_field(CiConstant, kind, "Lcom/sun/cri/ci/CiKind;") \ - oop_field(CiConstant, object, "Ljava/lang/Object;") \ - long_field(CiConstant, primitive) \ - end_class \ - start_class(CiKind) \ - char_field(CiKind, typeChar) \ - end_class \ - start_class(CiRuntimeCall) \ - static_oop_field(CiRuntimeCall, Debug, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ - end_class \ - start_class(RiMethod) \ - end_class \ - start_class(CiRegisterValue) \ - end_class \ - start_class(CiStackSlot) \ - end_class \ - /* end*/ - -#define START_CLASS(name) \ - class name : AllStatic { \ - private: \ - friend class C1XCompiler; \ - static void check(oop obj) { assert(obj != NULL, "NULL field access"); assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected"); } \ - static void compute_offsets(); \ - public: \ - static klassOop klass() { return SystemDictionary::name##_klass(); } - -#define END_CLASS }; - -#define FIELD(name, type, accessor) \ - static int _##name##_offset; \ - static type name(oop obj) { check(obj); return obj->accessor(_##name##_offset); } \ - static type name(jobject obj) { check(JNIHandles::resolve(obj)); return JNIHandles::resolve(obj)->accessor(_##name##_offset); } \ - static void set_##name(oop obj, type x) { check(obj); obj->accessor##_put(_##name##_offset, x); } \ - static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj)); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); } - -#define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field) -#define INT_FIELD(klass, name) FIELD(name, jint, int_field) -#define LONG_FIELD(klass, name) FIELD(name, jlong, long_field) -#define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field) -#define STATIC_OOP_FIELD(klassName, name, signature) \ - static int _##name##_offset; \ - static oop name() { return klassName::klass()->obj_field(_##name##_offset); } \ - static void set_##name(oop x) { klassName::klass()->obj_field_put(_##name##_offset, x); } - -COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) -#undef START_CLASS -#undef END_CLASS -#undef FIELD -#undef CHAR_FIELD -#undef INT_FIELD -#undef LONG_FIELD -#undef OOP_FIELD -#undef STATIC_OOP_FIELD - - diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_TargetMethod.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_TargetMethod.cpp Thu Aug 19 14:34:52 2010 -0700 @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + + +# include "incls/_precompiled.incl" +# include "incls/_c1x_TargetMethod.cpp.incl" + +static void compute_offset(int &dest_offset, klassOop klass_oop, const char* name, const char* signature, bool static_field) { + symbolOop name_symbol = SymbolTable::probe(name, strlen(name)); + symbolOop signature_symbol = SymbolTable::probe(signature, strlen(signature)); + assert(name_symbol != NULL, "symbol not found - class layout changed?"); + assert(signature_symbol != NULL, "symbol not found - class layout changed?"); + + instanceKlass* ik = instanceKlass::cast(klass_oop); + fieldDescriptor fd; + if (!ik->find_field(name_symbol, signature_symbol, &fd)) { + ResourceMark rm; + tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string()); + fatal("Invalid layout of preloaded class"); + } + assert(fd.is_static() == static_field, "static/instance mismatch"); + dest_offset = fd.offset(); +} + +// create the compute_class +#define START_CLASS(name) { klassOop k = SystemDictionary::name##_klass(); + +#define END_CLASS } + +#define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field); +#define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false) +#define INT_FIELD(klass, name) FIELD(klass, name, "I", false) +#define LONG_FIELD(klass, name) FIELD(klass, name, "J", false) +#define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false) +#define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true) + + +void c1x_compute_offsets() { + COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) +} + +#define EMPTY0 +#define EMPTY1(x) +#define EMPTY2(x,y) +#define FIELD2(klass, name) int klass::_##name##_offset = 0; +#define FIELD3(klass, name, sig) FIELD2(klass, name) + +COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3) + + + + + diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_TargetMethod.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_TargetMethod.hpp Thu Aug 19 14:34:52 2010 -0700 @@ -0,0 +1,150 @@ +/* + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +void c1x_compute_offsets(); + +// defines the structure of the CiTargetMethod - classes +// this will generate classes with accessors similar to javaClasses.hpp + +#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, long_field, oop_field, static_oop_field) \ + start_class(HotSpotTypeResolved) \ + long_field(HotSpotTypeResolved, vmId) \ + end_class \ + start_class(HotSpotMethod) \ + long_field(HotSpotMethod, vmId) \ + end_class \ + start_class(HotSpotTargetMethod) \ + oop_field(HotSpotTargetMethod, targetMethod, "Lcom/sun/cri/ci/CiTargetMethod;") \ + oop_field(HotSpotTargetMethod, method, "Lcom/sun/hotspot/c1x/HotSpotMethod;") \ + oop_field(HotSpotTargetMethod, name, "Ljava/lang/String;") \ + oop_field(HotSpotTargetMethod, sites, "[Lcom/sun/cri/ci/CiTargetMethod$Site;") \ + end_class \ + start_class(CiTargetMethod) \ + int_field(CiTargetMethod, frameSize) \ + oop_field(CiTargetMethod, targetCode, "[B") \ + int_field(CiTargetMethod, targetCodeSize) \ + int_field(CiTargetMethod, referenceRegisterCount) \ + end_class \ + start_class(CiTargetMethod_Site) \ + int_field(CiTargetMethod_Site, pcOffset) \ + end_class \ + start_class(CiTargetMethod_Call) \ + oop_field(CiTargetMethod_Call, runtimeCall, "Lcom/sun/cri/ci/CiRuntimeCall;") \ + oop_field(CiTargetMethod_Call, method, "Lcom/sun/cri/ri/RiMethod;") \ + oop_field(CiTargetMethod_Call, symbol, "Ljava/lang/String;") \ + oop_field(CiTargetMethod_Call, globalStubID, "Ljava/lang/Object;") \ + oop_field(CiTargetMethod_Call, debugInfo, "Lcom/sun/cri/ci/CiDebugInfo;") \ + oop_field(CiTargetMethod_Call, stackMap, "[B") \ + oop_field(CiTargetMethod_Call, registerMap, "[B") \ + end_class \ + start_class(CiTargetMethod_DataPatch) \ + oop_field(CiTargetMethod_DataPatch, constant, "Lcom/sun/cri/ci/CiConstant;") \ + end_class \ + start_class(CiTargetMethod_Safepoint) \ + oop_field(CiTargetMethod_Safepoint, debugInfo, "Lcom/sun/cri/ci/CiDebugInfo;") \ + end_class \ + start_class(CiTargetMethod_ExceptionHandler) \ + int_field(CiTargetMethod_ExceptionHandler, handlerPos) \ + oop_field(CiTargetMethod_ExceptionHandler, exceptionType, "Lcom/sun/cri/ri/RiType;")\ + end_class \ + start_class(CiTargetMethod_Mark) \ + oop_field(CiTargetMethod_Mark, id, "Ljava/lang/Object;") \ + oop_field(CiTargetMethod_Mark, references, "[Lcom/sun/cri/ci/CiTargetMethod$Mark;") \ + end_class \ + start_class(CiDebugInfo) \ + oop_field(CiDebugInfo, codePos, "Lcom/sun/cri/ci/CiCodePos;") \ + oop_field(CiDebugInfo, frame, "Lcom/sun/cri/ci/CiDebugInfo$Frame;") \ + oop_field(CiDebugInfo, registerRefMap, "[B") \ + oop_field(CiDebugInfo, frameRefMap, "[B") \ + end_class \ + start_class(CiDebugInfo_Frame) \ + oop_field(CiDebugInfo_Frame, caller, "Lcom/sun/cri/ci/CiDebugInfo$Frame;") \ + oop_field(CiDebugInfo_Frame, codePos, "Lcom/sun/cri/ci/CiCodePos;") \ + oop_field(CiDebugInfo_Frame, values, "[Lcom/sun/cri/ci/CiValue;") \ + int_field(CiDebugInfo_Frame, numLocals) \ + int_field(CiDebugInfo_Frame, numStack) \ + int_field(CiDebugInfo_Frame, numLocks) \ + end_class \ + start_class(CiCodePos) \ + oop_field(CiCodePos, caller, "Lcom/sun/cri/ci/CiCodePos;") \ + oop_field(CiCodePos, method, "Lcom/sun/cri/ri/RiMethod;") \ + int_field(CiCodePos, bci) \ + end_class \ + start_class(CiConstant) \ + oop_field(CiConstant, kind, "Lcom/sun/cri/ci/CiKind;") \ + oop_field(CiConstant, object, "Ljava/lang/Object;") \ + long_field(CiConstant, primitive) \ + end_class \ + start_class(CiKind) \ + char_field(CiKind, typeChar) \ + end_class \ + start_class(CiRuntimeCall) \ + static_oop_field(CiRuntimeCall, Debug, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + end_class \ + start_class(RiMethod) \ + end_class \ + start_class(CiRegisterValue) \ + end_class \ + start_class(CiStackSlot) \ + end_class \ + /* end*/ + +#define START_CLASS(name) \ + class name : AllStatic { \ + private: \ + friend class C1XCompiler; \ + static void check(oop obj) { assert(obj != NULL, "NULL field access"); assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected"); } \ + static void compute_offsets(); \ + public: \ + static klassOop klass() { return SystemDictionary::name##_klass(); } + +#define END_CLASS }; + +#define FIELD(name, type, accessor) \ + static int _##name##_offset; \ + static type name(oop obj) { check(obj); return obj->accessor(_##name##_offset); } \ + static type name(jobject obj) { check(JNIHandles::resolve(obj)); return JNIHandles::resolve(obj)->accessor(_##name##_offset); } \ + static void set_##name(oop obj, type x) { check(obj); obj->accessor##_put(_##name##_offset, x); } \ + static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj)); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); } + +#define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field) +#define INT_FIELD(klass, name) FIELD(name, jint, int_field) +#define LONG_FIELD(klass, name) FIELD(name, jlong, long_field) +#define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field) +#define STATIC_OOP_FIELD(klassName, name, signature) \ + static int _##name##_offset; \ + static oop name() { return klassName::klass()->obj_field(_##name##_offset); } \ + static void set_##name(oop x) { klassName::klass()->obj_field_put(_##name##_offset, x); } + +COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) +#undef START_CLASS +#undef END_CLASS +#undef FIELD +#undef CHAR_FIELD +#undef INT_FIELD +#undef LONG_FIELD +#undef OOP_FIELD +#undef STATIC_OOP_FIELD + + diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_VMEntries.cpp --- a/src/share/vm/c1x/c1x_VMEntries.cpp Wed Aug 18 16:47:06 2010 -0700 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Thu Aug 19 14:34:52 2010 -0700 @@ -31,7 +31,7 @@ // public byte[] RiMethod_code(long vmId); JNIEXPORT jbyteArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code(JNIEnv *env, jobject, jlong vmId) { - methodOop method = C1XObjects::get(vmId); + methodOop method = VmIds::get(vmId); int code_size = method->code_size(); jbyteArray result = env->NewByteArray(code_size); env->SetByteArrayRegion(result, 0, code_size, (const jbyte *)method->code_base()); @@ -40,20 +40,20 @@ // public int RiMethod_maxStackSize(long vmId); JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxStackSize(JNIEnv *, jobject, jlong vmId) { - return C1XObjects::get(vmId)->max_stack(); + return VmIds::get(vmId)->max_stack(); } // public int RiMethod_maxLocals(long vmId); JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1maxLocals(JNIEnv *, jobject, jlong vmId) { - return C1XObjects::get(vmId)->max_locals(); + return VmIds::get(vmId)->max_locals(); } // public RiType RiMethod_holder(long vmId); JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder(JNIEnv *, jobject, jlong vmId) { VM_ENTRY_MARK - klassOop klass = C1XObjects::get(vmId)->method_holder(); - jlong klassVmId = C1XObjects::add(klass); - Handle name = C1XObjects::toString(klass->klass_part()->name(), CHECK_NULL); + klassOop klass = VmIds::get(vmId)->method_holder(); + jlong klassVmId = VmIds::add(klass); + Handle name = VmIds::toString(klass->klass_part()->name(), CHECK_NULL); oop holder = VMExits::createRiType(klassVmId, name, THREAD); return JNIHandles::make_local(THREAD, holder); } @@ -61,20 +61,20 @@ // public String RiMethod_signature(long vmId); JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jlong vmId) { VM_ENTRY_MARK - methodOop method = C1XObjects::get(vmId); - return C1XObjects::toString(method->signature(), THREAD); + methodOop method = VmIds::get(vmId); + return VmIds::toString(method->signature(), THREAD); } // public int RiMethod_accessFlags(long vmId); JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags(JNIEnv *, jobject, jlong vmId) { - return C1XObjects::get(vmId)->access_flags().as_int(); + return VmIds::get(vmId)->access_flags().as_int(); } // public RiType RiSignature_lookupType(String returnType, long accessingClassVmId); JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *, jobject, jstring jname, jlong accessingClassVmId) { VM_ENTRY_MARK; - symbolOop nameSymbol = C1XObjects::toSymbol(jname); + symbolOop nameSymbol = VmIds::toSymbol(jname); Handle name = JNIHandles::resolve(jname); oop result; @@ -98,12 +98,12 @@ Handle classloader; Handle protectionDomain; if (accessingClassVmId != 0) { - classloader = C1XObjects::get(accessingClassVmId)->klass_part()->class_loader(); - protectionDomain = C1XObjects::get(accessingClassVmId)->klass_part()->protection_domain(); + classloader = VmIds::get(accessingClassVmId)->klass_part()->class_loader(); + protectionDomain = VmIds::get(accessingClassVmId)->klass_part()->protection_domain(); } klassOop resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); if (resolved_type != NULL) { - result = VMExits::createRiType(C1XObjects::add(resolved_type), name, THREAD); + result = VMExits::createRiType(VmIds::add(resolved_type), name, THREAD); } else { result = VMExits::createRiTypeUnresolved(name, accessingClassVmId, THREAD); } @@ -116,7 +116,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jlong vmId, jint index) { VM_ENTRY_MARK; - constantPoolOop cp = C1XObjects::get(vmId); + constantPoolOop cp = VmIds::get(vmId); oop result = NULL; constantTag tag = cp->tag_at(index); @@ -141,7 +141,7 @@ return NULL; } } - result = VMExits::createCiConstantObject(C1XObjects::add(string), CHECK_0); + result = VMExits::createCiConstantObject(VmIds::add(string), CHECK_0); } else if (tag.is_klass() || tag.is_unresolved_klass()) { // TODO: Return RiType object @@ -160,7 +160,7 @@ } else if (tag.is_object()) { oop obj = cp->object_at(index); assert(obj->is_instance(), "must be an instance"); - result = VMExits::createCiConstantObject(C1XObjects::add(obj), CHECK_0); + result = VMExits::createCiConstantObject(VmIds::add(obj), CHECK_0); } else { ShouldNotReachHere(); } @@ -172,14 +172,14 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) { VM_ENTRY_MARK; - constantPoolOop cp = C1XObjects::get(vmId); + constantPoolOop cp = VmIds::get(vmId); Bytecodes::Code bc = (Bytecodes::Code)(((int)byteCode) & 0xFF); ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder()); ciMethod *cimethod = CURRENT_ENV->get_method_by_index(cp, index, bc, loading_klass); methodOop method = (methodOop)cimethod->get_oop(); - Handle name = C1XObjects::toString(method->name(), CHECK_NULL); - return JNIHandles::make_local(THREAD, VMExits::createRiMethod(C1XObjects::add(method), name, THREAD)); + Handle name = VmIds::toString(method->name(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMExits::createRiMethod(VmIds::add(method), name, THREAD)); } // public RiSignature RiConstantPool_lookupSignature(long vmId, int cpi); @@ -192,7 +192,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType(JNIEnv *env, jobject, jlong vmId, jint index) { VM_ENTRY_MARK; - constantPoolOop cp = C1XObjects::get(vmId); + constantPoolOop cp = VmIds::get(vmId); ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder()); bool is_accessible = false; @@ -205,7 +205,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField(JNIEnv *env, jobject, jlong vmId, jint index) { VM_ENTRY_MARK; - constantPoolOop cp = C1XObjects::get(vmId); + constantPoolOop cp = VmIds::get(vmId); ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder()); ciField *field = CURRENT_ENV->get_field_by_index(loading_klass, index); @@ -216,28 +216,28 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool(JNIEnv *, jobject, jlong vmId) { VM_ENTRY_MARK; - constantPoolOop constantPool = instanceKlass::cast(C1XObjects::get(vmId))->constants(); - return JNIHandles::make_local(VMExits::createRiConstantPool(C1XObjects::add(constantPool), THREAD)); + constantPoolOop constantPool = instanceKlass::cast(VmIds::get(vmId))->constants(); + return JNIHandles::make_local(VMExits::createRiConstantPool(VmIds::add(constantPool), THREAD)); } // public boolean RiType_isArrayClass(long vmId); JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass(JNIEnv *, jobject, jlong vmId) { - return C1XObjects::get(vmId)->klass_part()->oop_is_javaArray(); + return VmIds::get(vmId)->klass_part()->oop_is_javaArray(); } // public boolean RiType_isInstanceClass(long vmId); JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass(JNIEnv *, jobject, jlong vmId) { - return C1XObjects::get(vmId)->klass_part()->oop_is_instance(); + return VmIds::get(vmId)->klass_part()->oop_is_instance(); } // public boolean RiType_isInterface(long vmId); JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface(JNIEnv *, jobject, jlong vmId) { - return C1XObjects::get(vmId)->klass_part()->is_interface(); + return VmIds::get(vmId)->klass_part()->is_interface(); } // public long RiType_instanceSize(long vmId); JNIEXPORT jlong JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1instanceSize(JNIEnv *, jobject, jlong vmId) { - return align_object_size(instanceKlass::cast(C1XObjects::get(vmId))->size_helper() * HeapWordSize); + return align_object_size(instanceKlass::cast(VmIds::get(vmId))->size_helper() * HeapWordSize); } @@ -287,10 +287,11 @@ set_int(env, config, "threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset())); set_int(env, config, "instanceHeaderPrototypeOffset", Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); - set_long(env, config, "instanceofStub", C1XObjects::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); - set_long(env, config, "debugStub", C1XObjects::addStub((address)warning)); - set_long(env, config, "resolveStaticCallStub", C1XObjects::addStub(SharedRuntime::get_resolve_static_call_stub())); - set_long(env, config, "newInstanceStub", C1XObjects::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_id))); + set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); + set_long(env, config, "debugStub", VmIds::addStub((address)warning)); + set_long(env, config, "resolveStaticCallStub", VmIds::addStub(SharedRuntime::get_resolve_static_call_stub())); + set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_id))); + set_long(env, config, "throwImplicitNullStub", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id))); jintArray arrayOffsets = env->NewIntArray(basicTypeCount); for (int i=0; ias_VMReg(); - } else { - assert(c1x_reg < C1X_REGISTER_COUNT, "invalid register number"); - return xmm_registers[c1x_reg - 16]->as_VMReg(); - } - -} - -static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) { - OopMap* map = new OopMap(frame_size, parameter_count); - arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info); - arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info); - - for (jint i=0; ibase(T_BYTE))[i / 8]; - bool is_oop = (byte & (1 << (i % 8))) != 0; - VMReg reg = get_hotspot_reg(i); - if (is_oop) { - map->set_oop(reg); - } else { - map->set_value(reg); - } - } - - for (jint i=0; ibase(T_BYTE))[i / 8]; - bool is_oop = (byte & (1 << (i % 8))) != 0; - VMReg reg = VMRegImpl::stack2reg(i); - if (is_oop) { - map->set_oop(reg); - } else { - map->set_value(reg); - } - } - - // TODO parameters? - return map; -} - -static ScopeValue* get_hotspot_value(oop value) { - fatal("not implemented"); - if (value->is_a(CiRegisterValue::klass())) { - tty->print("register value"); - value->print(); - } else if (value->is_a(CiStackSlot::klass())) { - tty->print("stack value"); - value->print(); - } else { - ShouldNotReachHere(); - } -} - - -class CodeInstaller { -private: - ciEnv* _env; - - oop _citarget_method; - oop _hotspot_method; - oop _name; - arrayOop _sites; - CodeOffsets _offsets; - - arrayOop _code; - jint _code_size; - jint _frame_size; - jint _parameter_count; - jint _constants_size; - jint _total_size; - - C1XCompiler::MarkId _next_call_type; - address _invoke_mark_pc; - - CodeSection* _instructions; - CodeSection* _constants; - - OopRecorder* _oop_recorder; - DebugInformationRecorder* _debug_recorder; - Dependencies* _dependencies; - -public: - - // constructor used to create a method - CodeInstaller(oop target_method) { - VM_ENTRY_MARK; - _env = CURRENT_ENV; - - initialize_fields(target_method); - assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name"); - - - // TODO: This is a hack.. Produce correct entries. - _offsets.set_value(CodeOffsets::Exceptions, 0); - _offsets.set_value(CodeOffsets::Deopt, 0); - - methodOop method = C1XObjects::get(HotSpotMethod::vmId(_hotspot_method)); - ciMethod *ciMethodObject = (ciMethod *)_env->get_object(method); - _parameter_count = method->size_of_parameters(); - - // (very) conservative estimate: each site needs a relocation - CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit); - initialize_buffer(buffer); - ExceptionHandlerTable handler_table; - ImplicitExceptionTable inc_table; - { - ThreadToNativeFromVM t((JavaThread*)THREAD); - _env->register_method(ciMethodObject, -1, &_offsets, 0, &buffer, _frame_size, _debug_recorder->_oopmaps, &handler_table, &inc_table, NULL, _env->comp_level(), false, false); - } - } - - // constructor used to create a stub - CodeInstaller(oop target_method, jlong& id) { - VM_ENTRY_MARK; - _env = CURRENT_ENV; - - initialize_fields(target_method); - assert(_hotspot_method == NULL && _name != NULL, "installMethod needs NON-NULL name and NULL method"); - - // (very) conservative estimate: each site needs a relocation - CodeBuffer buffer("temp c1x stub", _total_size, _sites->length() * relocInfo::length_limit); - initialize_buffer(buffer); - - const char* cname = java_lang_String::as_utf8_string(_name); - BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created - Disassembler::decode((CodeBlob*)blob); - id = C1XObjects::addStub(blob->instructions_begin()); - } - -private: - void initialize_fields(oop target_method) { - _citarget_method = HotSpotTargetMethod::targetMethod(target_method); - _hotspot_method = HotSpotTargetMethod::method(target_method); - _name = HotSpotTargetMethod::name(target_method); - _sites = (arrayOop)HotSpotTargetMethod::sites(target_method); - - _code = (arrayOop)CiTargetMethod::targetCode(_citarget_method); - _code_size = CiTargetMethod::targetCodeSize(_citarget_method); - _frame_size = CiTargetMethod::frameSize(_citarget_method); - - // (very) conservative estimate: each site needs a constant section entry - _constants_size = _sites->length() * BytesPerLong; - _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size; - - _next_call_type = C1XCompiler::MARK_INVOKE_INVALID; - } - - void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { - - } - - void record_frame(jint pc_offset, oop code_pos, oop frame) { - oop caller_pos = CiCodePos::caller(code_pos); - if (caller_pos != NULL) { - oop caller_frame = CiDebugInfo_Frame::caller(frame); - record_frame(pc_offset, caller_pos, caller_frame); - } else { - assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - different nesting of Frame and CiCodePos"); - } - - assert(frame == NULL || code_pos == CiDebugInfo_Frame::codePos(frame), "unexpected CiCodePos layout"); - - oop hotspot_method = CiCodePos::method(code_pos); - methodOop method = C1XObjects::get(HotSpotMethod::vmId(hotspot_method)); - ciMethod *cimethod = (ciMethod *)_env->get_object(method); - jint bci = CiCodePos::bci(code_pos); - - if (frame != NULL) { - jint local_count = CiDebugInfo_Frame::numLocals(frame); - jint expression_count = CiDebugInfo_Frame::numStack(frame); - jint monitor_count = CiDebugInfo_Frame::numLocks(frame); - arrayOop values = (arrayOop)CiDebugInfo_Frame::values(frame); - - assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); - assert(monitor_count == 0, "monitors not supported"); - - GrowableArray* locals = new GrowableArray(); - GrowableArray* expressions = new GrowableArray(); - GrowableArray* monitors = new GrowableArray(); - - for (jint i=0; ilength(); i++) { - ScopeValue* value = get_hotspot_value(((oop*)values->base(T_OBJECT))[i]); - - if (i < local_count) { - locals->append(value); - } else if (i < local_count + expression_count) { - expressions->append(value); - } else { - ShouldNotReachHere(); - // monitors->append(value); - } - } - DebugToken* locals_token = _debug_recorder->create_scope_values(locals); - DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); - DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); - - _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, locals_token, expressions_token, monitors_token); - } else { - _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, NULL, NULL, NULL); - } - } - - void site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { - oop runtime_call = CiTargetMethod_Call::runtimeCall(site); - oop hotspot_method = CiTargetMethod_Call::method(site); - oop symbol = CiTargetMethod_Call::symbol(site); - oop global_stub = CiTargetMethod_Call::globalStubID(site); - - oop debug_info = CiTargetMethod_Call::debugInfo(site); - arrayOop stack_map = (arrayOop)CiTargetMethod_Call::stackMap(site); - arrayOop register_map = (arrayOop)CiTargetMethod_Call::registerMap(site); - - assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); - - address instruction = _instructions->start() + pc_offset; - address operand = Assembler::locate_operand(instruction, Assembler::call32_operand); - address next_instruction = Assembler::locate_next_instruction(instruction); - - if (runtime_call != NULL) { - if (runtime_call == CiRuntimeCall::Debug()) { - tty->print_cr("CiRuntimeCall::Debug()"); - } else { - runtime_call->print(); - } - tty->print_cr("runtime_call"); - } else if (global_stub != NULL) { - assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long"); - - jlong stub_id = global_stub->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); - address dest = C1XObjects::getStub(stub_id); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, runtime_call_Relocation::spec(), Assembler::call32_operand); - tty->print_cr("relocating (stub) %016x/%016x", instruction, operand); - } else if (symbol != NULL) { - tty->print_cr("symbol"); - } else { // method != NULL - assert(hotspot_method->is_a(SystemDictionary::HotSpotMethod_klass()), "unexpected RiMethod subclass"); - methodOop method = C1XObjects::get(HotSpotMethod::vmId(hotspot_method)); - - jint next_pc_offset = next_instruction - _instructions->start(); - - assert(debug_info != NULL, "debug info expected"); - _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); - oop code_pos = CiDebugInfo::codePos(debug_info); - oop frame = CiDebugInfo::frame(debug_info); - record_frame(next_pc_offset, code_pos, frame); - - switch(_next_call_type) { - case C1XCompiler::MARK_INVOKEVIRTUAL: - case C1XCompiler::MARK_INVOKEINTERFACE: { - assert(!method->is_static(), "cannot call static method with invokeinterface"); - - address dest = SharedRuntime::get_resolve_virtual_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); - break; - } - case C1XCompiler::MARK_INVOKESTATIC: { - assert(method->is_static(), "cannot call non-static method with invokestatic"); - - address dest = SharedRuntime::get_resolve_static_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand); - break; - } - case C1XCompiler::MARK_INVOKESPECIAL: { - assert(!method->is_static(), "cannot call static method with invokespecial"); - - address dest = SharedRuntime::get_resolve_opt_virtual_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand); - break; - } - case C1XCompiler::MARK_INVOKE_INVALID: - default: - ShouldNotReachHere(); - break; - } - _next_call_type = C1XCompiler::MARK_INVOKE_INVALID; - _debug_recorder->end_safepoint(pc_offset); - } - } - - void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { - oop constant = CiTargetMethod_DataPatch::constant(site); - oop kind = CiConstant::kind(constant); - - address instruction = _instructions->start() + pc_offset; - - switch(CiKind::typeChar(kind)) { - case 'z': - case 'b': - case 's': - case 'c': - case 'i': - fatal("int-sized values not expected in DataPatch"); - break; - case 'f': - case 'l': - case 'd': { - address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); - address next_instruction = Assembler::locate_next_instruction(instruction); - // we don't care if this is a long/double/etc., the primitive field contains the right bits - address dest = _constants->end(); - *(jlong*)dest = CiConstant::primitive(constant); - _constants->set_end(dest + BytesPerLong); - - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - tty->print_cr("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); - break; - } - case 'a': { - address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); - oop obj = CiConstant::object(constant); - - if (obj->is_a(HotSpotTypeResolved::klass())) { - *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(HotSpotTypeResolved::vmId(obj))); - _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (HotSpotType) at %016x/%016x", instruction, operand); - } else { - assert(java_lang_boxing_object::is_instance(obj, T_LONG), "unexpected DataPatch object type"); - jlong id = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); - - assert((id & C1XObjects::TYPE_MASK) == C1XObjects::CONSTANT, "unexpected DataPatch type"); - - address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); - - if (id == C1XObjects::DUMMY_CONSTANT) { - *((jobject*)operand) = (jobject)Universe::non_oop_word(); - } else { - *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(id)); - } - _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (oop constant) at %016x/%016x", instruction, operand); - } - break; - } - default: - fatal("unexpected CiKind in DataPatch"); - break; - } - } - - void site_ExceptionHandler(CodeBuffer& buffer, jint pc_offset, oop site) { - - } - - void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { - oop id_obj = CiTargetMethod_Mark::id(site); - arrayOop references = (arrayOop)CiTargetMethod_Mark::references(site); - - if (id_obj != NULL) { - assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); - jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); - - address instruction = _instructions->start() + pc_offset; - - switch (id) { - case C1XCompiler::MARK_UNVERIFIED_ENTRY: - _offsets.set_value(CodeOffsets::Entry, pc_offset); - break; - case C1XCompiler::MARK_VERIFIED_ENTRY: - _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); - break; - case C1XCompiler::MARK_OSR_ENTRY: - _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); - break; - case C1XCompiler::MARK_STATIC_CALL_STUB: { - assert(references->length() == 1, "static call stub needs one reference"); - oop ref = ((oop*)references->base(T_OBJECT))[0]; - address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref); - _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); - break; - } - case C1XCompiler::MARK_INVOKE_INVALID: - case C1XCompiler::MARK_INVOKEINTERFACE: - case C1XCompiler::MARK_INVOKESTATIC: - case C1XCompiler::MARK_INVOKESPECIAL: - case C1XCompiler::MARK_INVOKEVIRTUAL: - _next_call_type = (C1XCompiler::MarkId)id; - _invoke_mark_pc = instruction; - break; - default: - ShouldNotReachHere(); - break; - } - } - } - - // perform data and call relocation on the CodeBuffer - void initialize_buffer(CodeBuffer& buffer) { - _oop_recorder = new OopRecorder(_env->arena()); - _env->set_oop_recorder(_oop_recorder); - _debug_recorder = new DebugInformationRecorder(_env->oop_recorder()); - _debug_recorder->set_oopmaps(new OopMapSet()); - _dependencies = new Dependencies(_env); - - _env->set_oop_recorder(_oop_recorder); - _env->set_debug_info(_debug_recorder); - _env->set_dependencies(_dependencies); - buffer.initialize_oop_recorder(_oop_recorder); - - buffer.initialize_consts_size(_constants_size); - _instructions = buffer.insts(); - _constants = buffer.consts(); - - // copy the code into the newly created CodeBuffer - memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); - _instructions->set_end(_instructions->start() + _code_size); - - oop* sites = (oop*)_sites->base(T_OBJECT); - for (int i=0; i<_sites->length(); i++) { - oop site = sites[i]; - jint pc_offset = CiTargetMethod_Site::pcOffset(site); - - if (site->is_a(CiTargetMethod_Safepoint::klass())) { - tty->print_cr("safepoint at %i", pc_offset); - site_Safepoint(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_Call::klass())) { - tty->print_cr("call at %i", pc_offset); - site_Call(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_DataPatch::klass())) { - tty->print_cr("datapatch at %i", pc_offset); - site_DataPatch(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_ExceptionHandler::klass())) { - tty->print_cr("exception handler at %i", pc_offset); - site_ExceptionHandler(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_Mark::klass())) { - tty->print_cr("mark at %i", pc_offset); - site_Mark(buffer, pc_offset, site); - } else { - ShouldNotReachHere(); - } - } - -/* - if (_relocation_count > 0) { - jint* relocation_offsets = (jint*)((arrayOop)JNIHandles::resolve(_relocation_offsets))->base(T_INT); - oop* relocation_objects = (oop*)((arrayOop)JNIHandles::resolve(_relocation_data))->base(T_OBJECT); - - for (int i = 0; i < _relocation_count; i++) { - address inst = (address)instructions->start() + relocation_offsets[i]; - u_char inst_byte = *inst; - oop obj = relocation_objects[i]; - assert(obj != NULL, "NULL oop needn't be patched"); - - if (obj->is_a(SystemDictionary::HotSpotProxy_klass())) { - jlong id = com_sun_hotspot_c1x_HotSpotProxy::get_id(obj); - switch (id & C1XObjects::TYPE_MASK) { - case C1XObjects::CONSTANT: { - address operand = Assembler::locate_operand(inst, Assembler::imm_operand); - - *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(id)); - instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); - break; - } - case C1XObjects::STUB: { - address operand = Assembler::locate_operand(inst, Assembler::call32_operand); - - long dest = (long)C1XObjects::getStub(id); - long disp = dest - (long)(operand + 4); - assert(disp == (int) disp, "disp doesn't fit in 32 bits"); - *((int*)operand) = (int)disp; - - instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand); - tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand); - break; - } - } - } else if (java_lang_boxing_object::is_instance(obj)) { - address operand = Assembler::locate_operand(inst, Assembler::disp32_operand); - long dest = (long)constants->end(); - if (java_lang_boxing_object::is_instance(obj, T_LONG)) { - // tty->print("relocate: %l\n", obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG))); - *(jlong*)constants->end() = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); - } else if (java_lang_boxing_object::is_instance(obj, T_DOUBLE)) { - // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); - *(jdouble*)constants->end() = obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE)); - } else if (java_lang_boxing_object::is_instance(obj, T_FLOAT)) { - // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); - *(jfloat*)constants->end() = obj->float_field(java_lang_boxing_object::value_offset_in_bytes(T_FLOAT)); - } - constants->set_end(constants->end() + 8); - - long disp = dest - (long)(operand + 4); - assert(disp == (int) disp, "disp doesn't fit in 32 bits"); - *((int*)operand) = (int)disp; - - instructions->relocate(inst, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - tty->print_cr("relocating (Long/Double) %02x at %016x/%016x", inst_byte, inst, operand); - } else if (obj->is_a(_types.HotSpotTypeResolved)) { - address operand = Assembler::locate_operand(inst, Assembler::imm_operand); - - *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(obj->obj_field(_types.HotSpotTypeResolved_klassOop))); - instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); - } else { - tty->print_cr("unknown relocation type"); - obj->print(); - } - } - }*/ - } -}; - // public void installMethod(HotSpotTargetMethod targetMethod); JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod) { CodeInstaller installer(JNIHandles::resolve(targetMethod)); diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_VmIds.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VmIds.cpp Thu Aug 19 14:34:52 2010 -0700 @@ -0,0 +1,84 @@ +/* + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +# include "incls/_precompiled.incl" +# include "incls/_c1x_VmIds.cpp.incl" + +// VmIds implementation + +GrowableArray
* VmIds::_stubs = NULL; +GrowableArray* VmIds::_localHandles = NULL; + +void VmIds::initializeObjects() { + if (_stubs == NULL) { + assert(_localHandles == NULL, "inconsistent state"); + _stubs = new(ResourceObj::C_HEAP) GrowableArray
(64, true); + _localHandles = new(ResourceObj::C_HEAP) GrowableArray(64, true); + } + assert(_localHandles->length() == 0, "invalid state"); +} + +void VmIds::cleanupLocalObjects() { + for (int i=0; i<_localHandles->length(); i++) { + JNIHandles::destroy_global(_localHandles->at(i)); + } + _localHandles->clear(); +} + +jlong VmIds::addStub(address stub) { + assert(!_stubs->contains(stub), "duplicate stub"); + return _stubs->append(stub) | STUB; +} + +jlong VmIds::add(Handle obj, CompilerObjectType type) { + assert(!obj.is_null(), "cannot add NULL handle"); + int idx = -1; + for (int i=0; i<_localHandles->length(); i++) + if (JNIHandles::resolve_non_null(_localHandles->at(i)) == obj()) { + idx = i; + break; + } + if (idx = -1) { + if (JavaThread::current()->thread_state() == _thread_in_vm) { + idx = _localHandles->append(JNIHandles::make_global(obj)); + } else { + VM_ENTRY_MARK; + idx = _localHandles->append(JNIHandles::make_global(obj)); + } + } + return idx | type; +} + +address VmIds::getStub(jlong id) { + assert((id & TYPE_MASK) == STUB, "wrong id type, STUB expected"); + assert((id & ~TYPE_MASK) >= 0 && (id & ~TYPE_MASK) < _stubs->length(), "STUB index out of bounds"); + return _stubs->at(id & ~TYPE_MASK); +} + +oop VmIds::getObject(jlong id) { + assert((id & TYPE_MASK) != STUB, "wrong id type"); + assert((id & ~TYPE_MASK) >= 0 && (id & ~TYPE_MASK) < _localHandles->length(), "index out of bounds"); + return JNIHandles::resolve_non_null(_localHandles->at(id & ~TYPE_MASK)); +} + diff -r 149b1d2316de -r 695451afc619 src/share/vm/c1x/c1x_VmIds.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/c1x/c1x_VmIds.hpp Thu Aug 19 14:34:52 2010 -0700 @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class VmIds : public AllStatic { + +private: + static GrowableArray
* _stubs; + static GrowableArray* _localHandles; + + static oop getObject(jlong id); + +public: + // this enum needs to have the same values as the one in HotSpotProxy.java + enum CompilerObjectType { + STUB = 0x100000000000000l, + METHOD = 0x200000000000000l, + CLASS = 0x300000000000000l, + SYMBOL = 0x400000000000000l, + CONSTANT_POOL = 0x500000000000000l, + CONSTANT = 0x600000000000000l, + TYPE_MASK = 0xf00000000000000l, + DUMMY_CONSTANT = 0x6ffffffffffffffl + }; + + static void initializeObjects(); + static void cleanupLocalObjects(); + + static jlong addStub(address stub); + static jlong add(Handle obj, CompilerObjectType type); + template static jlong add(T obj); + + static address getStub(jlong id); + template static T get(jlong id); + + template static T toString(symbolOop symbol, TRAPS); + static symbolOop toSymbol(jstring string); +}; + +template <> inline jlong VmIds::add(methodOop obj){ + assert(obj != NULL && obj->is_method(), "trying to add NULL or mistyped object"); + return add(Handle(obj), METHOD); +} +template <> inline jlong VmIds::add(klassOop obj) { + assert(obj != NULL && obj->is_klass(), "trying to add NULL or mistyped object"); + return add(Handle(obj), CLASS); +} +template <> inline jlong VmIds::add(symbolOop obj) { + assert(obj != NULL && obj->is_symbol(), "trying to add NULL or mistyped object"); + return add(Handle(obj), SYMBOL); +} +template <> inline jlong VmIds::add(constantPoolOop obj) { + assert(obj != NULL && obj->is_constantPool(), "trying to add NULL or mistyped object"); + return add(Handle(obj), CONSTANT_POOL); +} +template <> inline jlong VmIds::add(oop obj) { + assert(obj != NULL && obj->is_oop(), "trying to add NULL or mistyped object"); + return add(Handle(obj), CONSTANT); +} + +template <> inline methodOop VmIds::get(jlong id){ + assert((id & TYPE_MASK) == METHOD, "METHOD expected"); + assert(getObject(id)->is_method(), "methodOop expected"); + return (methodOop)getObject(id); +} +template <> inline klassOop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == CLASS, "CLASS expected"); + assert(getObject(id)->is_klass(), "klassOop expected"); + return (klassOop)getObject(id); +} +template <> inline symbolOop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == SYMBOL, "SYMBOL expected"); + assert(getObject(id)->is_symbol(), "symbolOop expected"); + return (symbolOop)getObject(id); +} +template <> inline constantPoolOop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == CONSTANT_POOL, "CONSTANT_POOL expected"); + assert(getObject(id)->is_constantPool(), "constantPoolOop expected"); + return (constantPoolOop)getObject(id); +} +template <> inline oop VmIds::get(jlong id) { + assert((id & TYPE_MASK) == CONSTANT, "CONSTANT expected"); + assert(getObject(id)->is_oop(true), "oop expected"); + return (oop)getObject(id); +} + +template <> inline Handle VmIds::toString(symbolOop symbol, TRAPS) { + return java_lang_String::create_from_symbol(symbol, THREAD); +} +template <> inline oop VmIds::toString(symbolOop symbol, TRAPS) { + return toString(symbol, THREAD)(); +} +template <> inline jstring VmIds::toString(symbolOop symbol, TRAPS) { + return (jstring)JNIHandles::make_local(toString(symbol, THREAD)); +} +template <> inline jobject VmIds::toString(symbolOop symbol, TRAPS) { + return JNIHandles::make_local(toString(symbol, THREAD)); +} + +inline symbolOop VmIds::toSymbol(jstring string) { + return java_lang_String::as_symbol_or_null(JNIHandles::resolve(string)); +} + diff -r 149b1d2316de -r 695451afc619 src/share/vm/includeDB_compiler1 --- a/src/share/vm/includeDB_compiler1 Wed Aug 18 16:47:06 2010 -0700 +++ b/src/share/vm/includeDB_compiler1 Thu Aug 19 14:34:52 2010 -0700 @@ -446,24 +446,37 @@ compileBroker.cpp c1x_Compiler.hpp +c1x_CodeInstaller.hpp c1x_Compiler.hpp + +c1x_CodeInstaller.cpp c1x_CodeInstaller.hpp +c1x_CodeInstaller.cpp c1x_Compiler.hpp +c1x_CodeInstaller.cpp c1x_TargetMethod.hpp +c1x_CodeInstaller.cpp c1x_VmIds.hpp +c1x_CodeInstaller.cpp c1_Runtime1.hpp + c1x_Compiler.hpp abstractCompiler.hpp c1x_Compiler.cpp c1x_Compiler.hpp +c1x_Compiler.cpp c1x_TargetMethod.hpp c1x_Compiler.cpp c1x_VMExits.hpp c1x_Compiler.cpp c1x_VMEntries.hpp +c1x_Compiler.cpp c1x_VmIds.hpp -c1x_VMEntries.hpp jni.h +c1x_TargetMethod.cpp c1x_TargetMethod.hpp -c1x_VMEntries.cpp c1x_Compiler.hpp +c1x_VMEntries.cpp c1x_CodeInstaller.hpp c1x_VMEntries.cpp c1x_VMEntries.hpp c1x_VMEntries.cpp c1x_Compiler.hpp +c1x_VMEntries.cpp c1x_TargetMethod.hpp c1x_VMEntries.cpp c1x_VMExits.hpp +c1x_VMEntries.cpp c1x_VmIds.hpp c1x_VMEntries.cpp oopFactory.hpp c1x_VMEntries.cpp c1_Runtime1.hpp -c1x_VMExits.hpp systemDictionary.hpp - c1x_VMExits.cpp c1x_Compiler.hpp c1x_VMExits.cpp javaCalls.hpp c1x_VMExits.cpp c1x_VMExits.hpp +c1x_VmIds.cpp c1x_VmIds.hpp + +