This commit is contained in:
Alejandro Murillo 2012-11-02 07:35:41 -07:00
commit d03b95a6e8
50 changed files with 421 additions and 2388 deletions

View File

@ -453,14 +453,30 @@ ifneq ($(OSNAME),windows)
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo): $(SHARK_DIR)/%.debuginfo
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(SHARK_DIR)/%.diz
$(install-file)
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_SERVER_DIR)/%.debuginfo: $(SHARK_DIR)/%.debuginfo
$(install-file)
$(EXPORT_SERVER_DIR)/%.diz: $(SHARK_DIR)/%.diz
$(install-file)
endif
ifeq ($(JVM_VARIANT_ZERO), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
$(install-file)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(ZERO_DIR)/%.diz
$(install-file)
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
$(install-file)
$(EXPORT_SERVER_DIR)/%.debuginfo: $(ZERO_DIR)/%.debuginfo
$(install-file)
$(EXPORT_SERVER_DIR)/%.diz: $(ZERO_DIR)/%.diz
$(install-file)
endif
ifeq ($(JVM_VARIANT_MINIMAL1), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(MINIMAL1_DIR)/%.$(LIBRARY_SUFFIX)

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=07
HS_BUILD_NUMBER=08
JDK_MAJOR_VER=1
JDK_MINOR_VER=8

View File

@ -31,12 +31,17 @@
return _masm;
}
protected:
address generate_entry(address entry_point) {
ZeroEntry *entry = (ZeroEntry *) assembler()->pc();
assembler()->advance(sizeof(ZeroEntry));
public:
static address generate_entry_impl(MacroAssembler* masm, address entry_point) {
ZeroEntry *entry = (ZeroEntry *) masm->pc();
masm->advance(sizeof(ZeroEntry));
entry->set_entry_point(entry_point);
return (address) entry;
}
protected:
address generate_entry(address entry_point) {
return generate_entry_impl(assembler(), entry_point);
}
#endif // CPU_ZERO_VM_CPPINTERPRETERGENERATOR_ZERO_HPP

View File

@ -180,25 +180,6 @@ void CppInterpreter::main_loop(int recurse, TRAPS) {
method, istate->osr_entry(), istate->osr_buf(), THREAD);
return;
}
else if (istate->msg() == BytecodeInterpreter::call_method_handle) {
oop method_handle = istate->callee();
// Trim back the stack to put the parameters at the top
stack->set_sp(istate->stack() + 1);
// Make the call
process_method_handle(method_handle, THREAD);
fixup_after_potential_safepoint();
// Convert the result
istate->set_stack(stack->sp() - 1);
// Restore the stack
stack->set_sp(istate->stack_limit() + 1);
// Resume the interpreter
istate->set_msg(BytecodeInterpreter::method_resume);
}
else {
ShouldNotReachHere();
}
@ -535,35 +516,35 @@ int CppInterpreter::accessor_entry(Method* method, intptr_t UNUSED, TRAPS) {
if (entry->is_volatile()) {
switch (entry->flag_state()) {
case ctos:
SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->char_field_acquire(entry->f2_as_index()), 0);
break;
case btos:
SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0);
break;
case stos:
SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->short_field_acquire(entry->f2_as_index()), 0);
break;
case itos:
SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0);
SET_LOCALS_INT(object->int_field_acquire(entry->f2_as_index()), 0);
break;
case ltos:
SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0);
SET_LOCALS_LONG(object->long_field_acquire(entry->f2_as_index()), 0);
break;
case ftos:
SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0);
SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2_as_index()), 0);
break;
case dtos:
SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0);
SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2_as_index()), 0);
break;
case atos:
SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0);
SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2_as_index()), 0);
break;
default:
@ -573,35 +554,35 @@ int CppInterpreter::accessor_entry(Method* method, intptr_t UNUSED, TRAPS) {
else {
switch (entry->flag_state()) {
case ctos:
SET_LOCALS_INT(object->char_field(entry->f2()), 0);
SET_LOCALS_INT(object->char_field(entry->f2_as_index()), 0);
break;
case btos:
SET_LOCALS_INT(object->byte_field(entry->f2()), 0);
SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0);
break;
case stos:
SET_LOCALS_INT(object->short_field(entry->f2()), 0);
SET_LOCALS_INT(object->short_field(entry->f2_as_index()), 0);
break;
case itos:
SET_LOCALS_INT(object->int_field(entry->f2()), 0);
SET_LOCALS_INT(object->int_field(entry->f2_as_index()), 0);
break;
case ltos:
SET_LOCALS_LONG(object->long_field(entry->f2()), 0);
SET_LOCALS_LONG(object->long_field(entry->f2_as_index()), 0);
break;
case ftos:
SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0);
SET_LOCALS_FLOAT(object->float_field(entry->f2_as_index()), 0);
break;
case dtos:
SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0);
SET_LOCALS_DOUBLE(object->double_field(entry->f2_as_index()), 0);
break;
case atos:
SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0);
SET_LOCALS_OBJECT(object->obj_field(entry->f2_as_index()), 0);
break;
default:
@ -629,516 +610,6 @@ int CppInterpreter::empty_entry(Method* method, intptr_t UNUSED, TRAPS) {
return 0;
}
int CppInterpreter::method_handle_entry(Method* method,
intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
int argument_slots = method->size_of_parameters();
int result_slots = type2size[result_type_of(method)];
intptr_t *vmslots = stack->sp();
intptr_t *unwind_sp = vmslots + argument_slots;
// Find the MethodType
address p = (address) method;
for (jint* pc = method->method_type_offsets_chain(); (*pc) != -1; pc++) {
p = *(address*)(p + (*pc));
}
oop method_type = (oop) p;
// The MethodHandle is in the slot after the arguments
int num_vmslots = argument_slots - 1;
oop method_handle = VMSLOTS_OBJECT(num_vmslots);
// InvokeGeneric requires some extra shuffling
oop mhtype = java_lang_invoke_MethodHandle::type(method_handle);
bool is_exact = mhtype == method_type;
if (!is_exact) {
if (true || // FIXME
method->intrinsic_id() == vmIntrinsics::_invokeExact) {
CALL_VM_NOCHECK_NOFIX(
SharedRuntime::throw_WrongMethodTypeException(
thread, method_type, mhtype));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
stack->set_sp(unwind_sp);
return 0;
}
assert(method->intrinsic_id() == vmIntrinsics::_invokeGeneric, "should be");
// Load up an adapter from the calling type
// NB the x86 code for this (in methodHandles_x86.cpp, search for
// "genericInvoker") is really really odd. I'm hoping it's trying
// to accomodate odd VM/class library combinations I can ignore.
oop adapter = NULL; //FIXME: load the adapter from the CP cache
IF (adapter == NULL) {
CALL_VM_NOCHECK_NOFIX(
SharedRuntime::throw_WrongMethodTypeException(
thread, method_type, mhtype));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
stack->set_sp(unwind_sp);
return 0;
}
// Adapters are shared among form-families of method-type. The
// type being called is passed as a trusted first argument so that
// the adapter knows the actual types of its arguments and return
// values.
insert_vmslots(num_vmslots + 1, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// NB all oops trashed!
stack->set_sp(unwind_sp);
return 0;
}
vmslots = stack->sp();
num_vmslots++;
SET_VMSLOTS_OBJECT(method_type, num_vmslots);
method_handle = adapter;
}
// Start processing
process_method_handle(method_handle, THREAD);
if (HAS_PENDING_EXCEPTION)
result_slots = 0;
// If this is an invokeExact then the eventual callee will not
// have unwound the method handle argument so we have to do it.
// If a result is being returned the it will be above the method
// handle argument we're unwinding.
if (is_exact) {
intptr_t result[2];
for (int i = 0; i < result_slots; i++)
result[i] = stack->pop();
stack->pop();
for (int i = result_slots - 1; i >= 0; i--)
stack->push(result[i]);
}
// Check
assert(stack->sp() == unwind_sp - result_slots, "should be");
// No deoptimized frames on the stack
return 0;
}
void CppInterpreter::process_method_handle(oop method_handle, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
intptr_t *vmslots = stack->sp();
bool direct_to_method = false;
BasicType src_rtype = T_ILLEGAL;
BasicType dst_rtype = T_ILLEGAL;
MethodHandleEntry *entry =
java_lang_invoke_MethodHandle::vmentry(method_handle);
MethodHandles::EntryKind entry_kind =
(MethodHandles::EntryKind) (((intptr_t) entry) & 0xffffffff);
Method* method = NULL;
switch (entry_kind) {
case MethodHandles::_invokestatic_mh:
direct_to_method = true;
break;
case MethodHandles::_invokespecial_mh:
case MethodHandles::_invokevirtual_mh:
case MethodHandles::_invokeinterface_mh:
{
oop receiver =
VMSLOTS_OBJECT(
java_lang_invoke_MethodHandle::vmslots(method_handle) - 1);
if (receiver == NULL) {
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_NullPointerException()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
if (entry_kind != MethodHandles::_invokespecial_mh) {
intptr_t index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle);
InstanceKlass* rcvrKlass =
(InstanceKlass *) receiver->klass();
if (entry_kind == MethodHandles::_invokevirtual_mh) {
method = (Method*) rcvrKlass->start_of_vtable()[index];
}
else {
oop iclass = java_lang_invoke_MethodHandle::next_target(method_handle);
itableOffsetEntry* ki =
(itableOffsetEntry *) rcvrKlass->start_of_itable();
int i, length = rcvrKlass->itable_length();
for (i = 0; i < length; i++, ki++ ) {
if (ki->interface_klass() == iclass)
break;
}
if (i == length) {
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_IncompatibleClassChangeError()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
itableMethodEntry* im = ki->first_method_entry(receiver->klass());
method = im[index].method();
if (method == NULL) {
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_AbstractMethodError()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
}
}
}
direct_to_method = true;
break;
case MethodHandles::_bound_ref_direct_mh:
case MethodHandles::_bound_int_direct_mh:
case MethodHandles::_bound_long_direct_mh:
direct_to_method = true;
// fall through
case MethodHandles::_bound_ref_mh:
case MethodHandles::_bound_int_mh:
case MethodHandles::_bound_long_mh:
{
BasicType arg_type = T_ILLEGAL;
int arg_mask = -1;
int arg_slots = -1;
MethodHandles::get_ek_bound_mh_info(
entry_kind, arg_type, arg_mask, arg_slots);
int arg_slot =
java_lang_invoke_BoundMethodHandle::vmargslot(method_handle);
// Create the new slot(s)
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
insert_vmslots(arg_slot, arg_slots, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
vmslots = stack->sp();
// Store bound argument into new stack slot
oop arg = java_lang_invoke_BoundMethodHandle::argument(method_handle);
if (arg_type == T_OBJECT) {
assert(arg_slots == 1, "should be");
SET_VMSLOTS_OBJECT(arg, arg_slot);
}
else {
jvalue arg_value;
arg_type = java_lang_boxing_object::get_value(arg, &arg_value);
switch (arg_type) {
case T_BOOLEAN:
SET_VMSLOTS_INT(arg_value.z, arg_slot);
break;
case T_CHAR:
SET_VMSLOTS_INT(arg_value.c, arg_slot);
break;
case T_BYTE:
SET_VMSLOTS_INT(arg_value.b, arg_slot);
break;
case T_SHORT:
SET_VMSLOTS_INT(arg_value.s, arg_slot);
break;
case T_INT:
SET_VMSLOTS_INT(arg_value.i, arg_slot);
break;
case T_FLOAT:
SET_VMSLOTS_FLOAT(arg_value.f, arg_slot);
break;
case T_LONG:
SET_VMSLOTS_LONG(arg_value.j, arg_slot + 1);
break;
case T_DOUBLE:
SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot + 1);
break;
default:
tty->print_cr("unhandled type %s", type2name(arg_type));
ShouldNotReachHere();
}
}
}
break;
case MethodHandles::_adapter_retype_only:
case MethodHandles::_adapter_retype_raw:
src_rtype = result_type_of_handle(
java_lang_invoke_MethodHandle::next_target(method_handle));
dst_rtype = result_type_of_handle(method_handle);
break;
case MethodHandles::_adapter_check_cast:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
oop arg = VMSLOTS_OBJECT(arg_slot);
if (arg != NULL) {
Klass* objKlassOop = arg->klass();
Klass* klassOf = java_lang_Class::as_Klass(
java_lang_invoke_AdapterMethodHandle::argument(method_handle));
if (objKlassOop != klassOf &&
!objKlassOop->is_subtype_of(klassOf)) {
ResourceMark rm(THREAD);
const char* objName = Klass::cast(objKlassOop)->external_name();
const char* klassName = Klass::cast(klassOf)->external_name();
char* message = SharedRuntime::generate_class_cast_message(
objName, klassName);
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_ClassCastException(), message));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
}
}
break;
case MethodHandles::_adapter_dup_args:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int conv =
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int num_slots = -MethodHandles::adapter_conversion_stack_move(conv);
assert(num_slots > 0, "should be");
// Create the new slot(s)
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
stack->overflow_check(num_slots, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
// Duplicate the arguments
for (int i = num_slots - 1; i >= 0; i--)
stack->push(*VMSLOTS_SLOT(arg_slot + i));
vmslots = stack->sp(); // unused, but let the compiler figure that out
}
break;
case MethodHandles::_adapter_drop_args:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int conv =
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int num_slots = MethodHandles::adapter_conversion_stack_move(conv);
assert(num_slots > 0, "should be");
remove_vmslots(arg_slot, num_slots, THREAD); // doesn't trap
vmslots = stack->sp(); // unused, but let the compiler figure that out
}
break;
case MethodHandles::_adapter_opt_swap_1:
case MethodHandles::_adapter_opt_swap_2:
case MethodHandles::_adapter_opt_rot_1_up:
case MethodHandles::_adapter_opt_rot_1_down:
case MethodHandles::_adapter_opt_rot_2_up:
case MethodHandles::_adapter_opt_rot_2_down:
{
int arg1 =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int conv =
java_lang_invoke_AdapterMethodHandle::conversion(method_handle);
int arg2 = MethodHandles::adapter_conversion_vminfo(conv);
int swap_bytes = 0, rotate = 0;
MethodHandles::get_ek_adapter_opt_swap_rot_info(
entry_kind, swap_bytes, rotate);
int swap_slots = swap_bytes >> LogBytesPerWord;
intptr_t tmp;
switch (rotate) {
case 0: // swap
for (int i = 0; i < swap_slots; i++) {
tmp = *VMSLOTS_SLOT(arg1 + i);
SET_VMSLOTS_SLOT(VMSLOTS_SLOT(arg2 + i), arg1 + i);
SET_VMSLOTS_SLOT(&tmp, arg2 + i);
}
break;
case 1: // up
assert(arg1 - swap_slots > arg2, "should be");
tmp = *VMSLOTS_SLOT(arg1);
for (int i = arg1 - swap_slots; i >= arg2; i--)
SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i + swap_slots);
SET_VMSLOTS_SLOT(&tmp, arg2);
break;
case -1: // down
assert(arg2 - swap_slots > arg1, "should be");
tmp = *VMSLOTS_SLOT(arg1);
for (int i = arg1 + swap_slots; i <= arg2; i++)
SET_VMSLOTS_SLOT(VMSLOTS_SLOT(i), i - swap_slots);
SET_VMSLOTS_SLOT(&tmp, arg2);
break;
default:
ShouldNotReachHere();
}
}
break;
case MethodHandles::_adapter_opt_i2l:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
int arg = VMSLOTS_INT(arg_slot);
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
insert_vmslots(arg_slot, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
vmslots = stack->sp();
arg_slot++;
SET_VMSLOTS_LONG(arg, arg_slot);
}
break;
case MethodHandles::_adapter_opt_unboxi:
case MethodHandles::_adapter_opt_unboxl:
{
int arg_slot =
java_lang_invoke_AdapterMethodHandle::vmargslot(method_handle);
oop arg = VMSLOTS_OBJECT(arg_slot);
jvalue arg_value;
if (arg == NULL) {
// queue a nullpointer exception for the caller
stack->set_sp(calculate_unwind_sp(stack, method_handle));
CALL_VM_NOCHECK_NOFIX(
throw_exception(
thread, vmSymbols::java_lang_NullPointerException()));
// NB all oops trashed!
assert(HAS_PENDING_EXCEPTION, "should do");
return;
}
BasicType arg_type = java_lang_boxing_object::get_value(arg, &arg_value);
if (arg_type == T_LONG || arg_type == T_DOUBLE) {
intptr_t *unwind_sp = calculate_unwind_sp(stack, method_handle);
insert_vmslots(arg_slot, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// all oops trashed
stack->set_sp(unwind_sp);
return;
}
vmslots = stack->sp();
arg_slot++;
}
switch (arg_type) {
case T_BOOLEAN:
SET_VMSLOTS_INT(arg_value.z, arg_slot);
break;
case T_CHAR:
SET_VMSLOTS_INT(arg_value.c, arg_slot);
break;
case T_BYTE:
SET_VMSLOTS_INT(arg_value.b, arg_slot);
break;
case T_SHORT:
SET_VMSLOTS_INT(arg_value.s, arg_slot);
break;
case T_INT:
SET_VMSLOTS_INT(arg_value.i, arg_slot);
break;
case T_FLOAT:
SET_VMSLOTS_FLOAT(arg_value.f, arg_slot);
break;
case T_LONG:
SET_VMSLOTS_LONG(arg_value.j, arg_slot);
break;
case T_DOUBLE:
SET_VMSLOTS_DOUBLE(arg_value.d, arg_slot);
break;
default:
tty->print_cr("unhandled type %s", type2name(arg_type));
ShouldNotReachHere();
}
}
break;
default:
tty->print_cr("unhandled entry_kind %s",
MethodHandles::entry_name(entry_kind));
ShouldNotReachHere();
}
// Continue along the chain
if (direct_to_method) {
if (method == NULL) {
method =
(Method*) java_lang_invoke_MethodHandle::vmtarget(method_handle);
}
address entry_point = method->from_interpreted_entry();
Interpreter::invoke_method(method, entry_point, THREAD);
}
else {
process_method_handle(
java_lang_invoke_MethodHandle::next_target(method_handle), THREAD);
}
// NB all oops now trashed
// Adapt the result type, if necessary
if (src_rtype != dst_rtype && !HAS_PENDING_EXCEPTION) {
switch (dst_rtype) {
case T_VOID:
for (int i = 0; i < type2size[src_rtype]; i++)
stack->pop();
return;
case T_INT:
switch (src_rtype) {
case T_VOID:
stack->overflow_check(1, CHECK);
stack->push(0);
return;
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
return;
}
// INT results sometimes need narrowing
case T_BOOLEAN:
case T_CHAR:
case T_BYTE:
case T_SHORT:
switch (src_rtype) {
case T_INT:
return;
}
}
tty->print_cr("unhandled conversion:");
tty->print_cr("src_rtype = %s", type2name(src_rtype));
tty->print_cr("dst_rtype = %s", type2name(dst_rtype));
ShouldNotReachHere();
}
}
// The new slots will be inserted before slot insert_before.
// Slots < insert_before will have the same slot number after the insert.
// Slots >= insert_before will become old_slot + num_slots.
@ -1380,10 +851,6 @@ address AbstractInterpreterGenerator::generate_method_entry(
entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();
break;
case Interpreter::method_handle:
entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();
break;
case Interpreter::java_lang_math_sin:
case Interpreter::java_lang_math_cos:
case Interpreter::java_lang_math_tan:
@ -1391,6 +858,8 @@ address AbstractInterpreterGenerator::generate_method_entry(
case Interpreter::java_lang_math_log:
case Interpreter::java_lang_math_log10:
case Interpreter::java_lang_math_sqrt:
case Interpreter::java_lang_math_pow:
case Interpreter::java_lang_math_exp:
entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);
break;

View File

@ -36,7 +36,6 @@
static int native_entry(Method* method, intptr_t UNUSED, TRAPS);
static int accessor_entry(Method* method, intptr_t UNUSED, TRAPS);
static int empty_entry(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry(Method* method, intptr_t UNUSED, TRAPS);
public:
// Main loop of normal_entry
@ -44,7 +43,6 @@
private:
// Helpers for method_handle_entry
static void process_method_handle(oop method_handle, TRAPS);
static void insert_vmslots(int insert_before, int num_slots, TRAPS);
static void remove_vmslots(int first_slot, int num_slots, TRAPS);
static BasicType result_type_of_handle(oop method_handle);

View File

@ -351,7 +351,7 @@ void SharkFrame::identify_word(int frame_index,
switch (offset) {
case pc_off:
strncpy(fieldbuf, "pc", buflen);
if (method()->is_oop()) {
if (method()->is_method()) {
nmethod *code = method()->code();
if (code && code->pc_desc_at(pc())) {
SimpleScopeDesc ssd(code, pc());
@ -367,7 +367,7 @@ void SharkFrame::identify_word(int frame_index,
case method_off:
strncpy(fieldbuf, "method", buflen);
if (method()->is_oop()) {
if (method()->is_method()) {
method()->name_and_sig_as_C_string(valuebuf, buflen);
}
return;
@ -378,7 +378,7 @@ void SharkFrame::identify_word(int frame_index,
}
// Variable part
if (method()->is_oop()) {
if (method()->is_method()) {
identify_vp_word(frame_index, addr_of_word(offset),
addr_of_word(header_words + 1),
unextended_sp() + method()->max_stack(),
@ -430,4 +430,3 @@ intptr_t *frame::initial_deoptimization_info() {
// unused... but returns fp() to minimize changes introduced by 7087445
return fp();
}

View File

@ -36,6 +36,8 @@ inline frame::frame() {
_deopt_state = unknown;
}
inline address frame::sender_pc() const { ShouldNotCallThis(); }
inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_zeroframe = zf;
_sp = sp;

View File

@ -40,7 +40,7 @@ int InlineCacheBuffer::ic_stub_code_size() {
}
void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin,
Metadata* cached_oop,
void* cached_oop,
address entry_point) {
// NB ic_stub_code_size() must return the size of the code we generate
ShouldNotCallThis();
@ -51,7 +51,6 @@ address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
ShouldNotCallThis();
}
Metadata* InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) {
// NB ic_stub_code_size() must return the size of the code we generate
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) {
ShouldNotCallThis();
}

View File

@ -24,26 +24,159 @@
*/
#include "precompiled.hpp"
#include "interpreter/interpreterGenerator.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/allocation.inline.hpp"
#include "prims/methodHandles.hpp"
int MethodHandles::adapter_conversion_ops_supported_mask() {
return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
|(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
//|(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) //BUG!
);
// FIXME: MethodHandlesTest gets a crash if we enable OP_SPREAD_ARGS.
void MethodHandles::invoke_target(Method* method, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
ZeroStack *stack = thread->zero_stack();
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
// Trim back the stack to put the parameters at the top
stack->set_sp(istate->stack() + 1);
Interpreter::invoke_method(method, method->from_interpreted_entry(), THREAD);
// Convert the result
istate->set_stack(stack->sp() - 1);
}
void MethodHandles::generate_method_handle_stub(MacroAssembler* masm,
MethodHandles::EntryKind ek) {
init_entry(ek, (MethodHandleEntry *) ek);
oop MethodHandles::popFromStack(TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
intptr_t* topOfStack = istate->stack();
oop top = STACK_OBJECT(-1);
MORE_STACK(-1);
istate->set_stack(topOfStack);
return top;
}
int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
intptr_t* topOfStack = istate->stack();
// 'this' is a MethodHandle. We resolve the target method by accessing this.form.vmentry.vmtarget.
int numArgs = method->size_of_parameters();
oop lform1 = java_lang_invoke_MethodHandle::form(STACK_OBJECT(-numArgs)); // this.form
oop vmEntry1 = java_lang_invoke_LambdaForm::vmentry(lform1);
Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmEntry1);
invoke_target(vmtarget, THREAD);
// No deoptimized frames on the stack
return 0;
}
int MethodHandles::method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS) {
// Pop appendix argument from stack. This is a MemberName which we resolve to the
// target method.
oop vmentry = popFromStack(THREAD);
Method* vmtarget = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
invoke_target(vmtarget, THREAD);
return 0;
}
int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
// Pop appendix argument from stack. This is a MemberName which we resolve to the
// target method.
oop vmentry = popFromStack(THREAD);
intptr_t* topOfStack = istate->stack();
// Resolve target method by looking up in the receiver object's itable.
Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(vmentry));
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry);
Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
int numArgs = target->size_of_parameters();
oop recv = STACK_OBJECT(-numArgs);
InstanceKlass* klass_part = InstanceKlass::cast(recv->klass());
itableOffsetEntry* ki = (itableOffsetEntry*) klass_part->start_of_itable();
int i;
for ( i = 0 ; i < klass_part->itable_length() ; i++, ki++ ) {
if (ki->interface_klass() == clazz) break;
}
itableMethodEntry* im = ki->first_method_entry(recv->klass());
Method* vmtarget = im[vmindex].method();
invoke_target(vmtarget, THREAD);
return 0;
}
int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
interpreterState istate = frame->interpreter_state();
// Pop appendix argument from stack. This is a MemberName which we resolve to the
// target method.
oop vmentry = popFromStack(THREAD);
intptr_t* topOfStack = istate->stack();
// Resolve target method by looking up in the receiver object's vtable.
intptr_t vmindex = java_lang_invoke_MemberName::vmindex(vmentry);
Method* target = (Method*) java_lang_invoke_MemberName::vmtarget(vmentry);
int numArgs = target->size_of_parameters();
oop recv = STACK_OBJECT(-numArgs);
Klass* clazz = recv->klass();
Klass* klass_part = InstanceKlass::cast(clazz);
klassVtable* vtable = klass_part->vtable();
Method* vmtarget = vtable->method_at(vmindex);
invoke_target(vmtarget, THREAD);
return 0;
}
int MethodHandles::method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS) {
ShouldNotReachHere();
return 0;
}
address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* masm,
vmIntrinsics::ID iid) {
switch (iid) {
case vmIntrinsics::_invokeGeneric:
case vmIntrinsics::_compiledLambdaForm:
// Perhaps surprisingly, the symbolic references visible to Java are not directly used.
// They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
// They all allow an appendix argument.
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invalid);
case vmIntrinsics::_invokeBasic:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_invokeBasic);
case vmIntrinsics::_linkToStatic:
case vmIntrinsics::_linkToSpecial:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToStaticOrSpecial);
case vmIntrinsics::_linkToInterface:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToInterface);
case vmIntrinsics::_linkToVirtual:
return InterpreterGenerator::generate_entry_impl(masm, (address) MethodHandles::method_handle_entry_linkToVirtual);
default:
ShouldNotReachHere();
return NULL;
}
}

View File

@ -26,6 +26,14 @@
// Adapters
enum /* platform_dependent_constants */ {
adapter_code_size = 0
adapter_code_size = sizeof(ZeroEntry) * (Interpreter::method_handle_invoke_LAST - Interpreter::method_handle_invoke_FIRST + 1)
};
private:
static oop popFromStack(TRAPS);
static void invoke_target(Method* method, TRAPS);
static int method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_linkToStaticOrSpecial(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS);
static int method_handle_entry_invalid(Method* method, intptr_t UNUSED, TRAPS);

View File

@ -114,5 +114,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
};
CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
#ifndef DONT_USE_REGISTER_DEFINES
#define noreg ((Register)(noreg_RegisterEnumValue))
#endif
#endif // CPU_ZERO_VM_REGISTER_ZERO_HPP

View File

@ -77,3 +77,7 @@ void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src,
CodeBuffer* dst) {
ShouldNotCallThis();
}
void metadata_Relocation::pd_fix_value(address x) {
ShouldNotCallThis();
}

View File

@ -35,6 +35,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/vframeArray.hpp"
#include "vmreg_zero.inline.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
@ -47,6 +48,12 @@
#endif
static address zero_null_code_stub() {
address start = ShouldNotCallThisStub();
return start;
}
int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
VMRegPair *regs,
int total_args_passed,
@ -63,16 +70,14 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(
AdapterFingerPrint *fingerprint) {
return AdapterHandlerLibrary::new_entry(
fingerprint,
ShouldNotCallThisStub(),
ShouldNotCallThisStub(),
ShouldNotCallThisStub());
CAST_FROM_FN_PTR(address,zero_null_code_stub),
CAST_FROM_FN_PTR(address,zero_null_code_stub),
CAST_FROM_FN_PTR(address,zero_null_code_stub));
}
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
methodHandle method,
int compile_id,
int total_args_passed,
int max_arg,
BasicType *sig_bt,
VMRegPair *regs,
BasicType ret_type) {
@ -96,19 +101,20 @@ uint SharedRuntime::out_preserve_stack_slots() {
ShouldNotCallThis();
}
JRT_LEAF(void, zero_stub())
ShouldNotCallThis();
JRT_END
static RuntimeStub* generate_empty_runtime_stub(const char* name) {
CodeBuffer buffer(name, 0, 0);
return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false);
return CAST_FROM_FN_PTR(RuntimeStub*,zero_stub);
}
static SafepointBlob* generate_empty_safepoint_blob() {
CodeBuffer buffer("handler_blob", 0, 0);
return SafepointBlob::create(&buffer, NULL, 0);
return CAST_FROM_FN_PTR(SafepointBlob*,zero_stub);
}
static DeoptimizationBlob* generate_empty_deopt_blob() {
CodeBuffer buffer("handler_blob", 0, 0);
return DeoptimizationBlob::create(&buffer, NULL, 0, 0, 0, 0);
return CAST_FROM_FN_PTR(DeoptimizationBlob*,zero_stub);
}
@ -116,7 +122,7 @@ void SharedRuntime::generate_deopt_blob() {
_deopt_blob = generate_empty_deopt_blob();
}
SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
return generate_empty_safepoint_blob();
}
@ -124,6 +130,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
return generate_empty_runtime_stub("resolve_blob");
}
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
VMRegPair *regs,
int total_args_passed) {

View File

@ -342,7 +342,6 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
// get the credentials of the peer and check the effective uid/guid
// - check with jeff on this.
#ifdef _ALLBSD_SOURCE
uid_t puid;
gid_t pgid;
if (::getpeereid(s, &puid, &pgid) != 0) {
@ -350,17 +349,6 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
RESTARTABLE(::close(s), res);
continue;
}
#else
struct ucred cred_info;
socklen_t optlen = sizeof(cred_info);
if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
int res;
RESTARTABLE(::close(s), res);
continue;
}
uid_t puid = cred_info.uid;
gid_t pgid = cred_info.gid;
#endif
uid_t euid = geteuid();
gid_t egid = getegid();

View File

@ -39,18 +39,12 @@
private:
#ifdef _ALLBSD_SOURCE
#ifdef __APPLE__
typedef thread_t thread_id_t;
#else
typedef pthread_t thread_id_t;
#endif
#else
typedef pid_t thread_id_t;
#endif
// _pthread_id is the pthread id, which is used by library calls
// (e.g. pthread_kill).
pthread_t _pthread_id;

File diff suppressed because it is too large Load Diff

View File

@ -56,19 +56,6 @@ class Bsd {
static int sigflags[MAXSIGNUM];
static int (*_clock_gettime)(clockid_t, struct timespec *);
#ifndef _ALLBSD_SOURCE
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
static address _initial_thread_stack_bottom;
static uintptr_t _initial_thread_stack_size;
static const char *_glibc_version;
static const char *_libpthread_version;
static bool _is_floating_stack;
static bool _is_NPTL;
static bool _supports_fast_thread_cpu_time;
#endif
static GrowableArray<int>* _cpu_to_node;
@ -76,28 +63,14 @@ class Bsd {
static julong _physical_memory;
static pthread_t _main_thread;
#ifndef _ALLBSD_SOURCE
static Mutex* _createThread_lock;
#endif
static int _page_size;
static julong available_memory();
static julong physical_memory() { return _physical_memory; }
static void initialize_system_info();
#ifndef _ALLBSD_SOURCE
static void set_glibc_version(const char *s) { _glibc_version = s; }
static void set_libpthread_version(const char *s) { _libpthread_version = s; }
#endif
static bool supports_variable_stack_size();
#ifndef _ALLBSD_SOURCE
static void set_is_NPTL() { _is_NPTL = true; }
static void set_is_BsdThreads() { _is_NPTL = false; }
static void set_is_floating_stack() { _is_floating_stack = true; }
#endif
static void rebuild_cpu_to_node_map();
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
@ -106,25 +79,10 @@ class Bsd {
public:
static void init_thread_fpu_state();
#ifndef _ALLBSD_SOURCE
static int get_fpu_control_word();
static void set_fpu_control_word(int fpu_control);
#endif
static pthread_t main_thread(void) { return _main_thread; }
#ifndef _ALLBSD_SOURCE
// returns kernel thread id (similar to LWP id on Solaris), which can be
// used to access /proc
static pid_t gettid();
static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
static Mutex* createThread_lock(void) { return _createThread_lock; }
#endif
static void hotspot_sigmask(Thread* thread);
#ifndef _ALLBSD_SOURCE
static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; }
static uintptr_t initial_thread_stack_size(void) { return _initial_thread_stack_size; }
#endif
static bool is_initial_thread(void);
static int page_size(void) { return _page_size; }
@ -161,23 +119,6 @@ class Bsd {
static struct sigaction *get_chained_signal_action(int sig);
static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
#ifndef _ALLBSD_SOURCE
// GNU libc and libpthread version strings
static const char *glibc_version() { return _glibc_version; }
static const char *libpthread_version() { return _libpthread_version; }
// NPTL or BsdThreads?
static bool is_BsdThreads() { return !_is_NPTL; }
static bool is_NPTL() { return _is_NPTL; }
// NPTL is always floating stack. BsdThreads could be using floating
// stack or fixed stack.
static bool is_floating_stack() { return _is_floating_stack; }
static void libpthread_init();
static bool libnuma_init();
static void* libnuma_dlsym(void* handle, const char* name);
#endif
// Minimum stack size a thread can be created with (allowing
// the VM to completely create the thread and enter user code)
static size_t min_stack_allowed;
@ -186,22 +127,9 @@ class Bsd {
static size_t default_stack_size(os::ThreadType thr_type);
static size_t default_guard_size(os::ThreadType thr_type);
#ifndef _ALLBSD_SOURCE
static void capture_initial_stack(size_t max_size);
// Stack overflow handling
static bool manually_expand_stack(JavaThread * t, address addr);
static int max_register_window_saves_before_flushing();
#endif
// Real-time clock functions
static void clock_init(void);
#ifndef _ALLBSD_SOURCE
// fast POSIX clocks support
static void fast_thread_clock_init(void);
#endif
static inline bool supports_monotonic_clock() {
return _clock_gettime != NULL;
}
@ -210,18 +138,6 @@ class Bsd {
return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;
}
#ifndef _ALLBSD_SOURCE
static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
}
static bool supports_fast_thread_cpu_time() {
return _supports_fast_thread_cpu_time;
}
static jlong fast_thread_cpu_time(clockid_t clockid);
#endif
// Stack repair handling
// none present

View File

@ -22,7 +22,7 @@
*
*/
// Must be at least Windows 2000 or XP to use VectoredExceptions and IsDebuggerPresent
// Must be at least Windows 2000 or XP to use IsDebuggerPresent
#define _WIN32_WINNT 0x500
// no precompiled headers
@ -110,10 +110,6 @@ static FILETIME process_exit_time;
static FILETIME process_user_time;
static FILETIME process_kernel_time;
#ifdef _WIN64
PVOID topLevelVectoredExceptionHandler = NULL;
#endif
#ifdef _M_IA64
#define __CPU__ ia64
#elif _M_AMD64
@ -136,12 +132,6 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
case DLL_PROCESS_DETACH:
if(ForceTimeHighResolution)
timeEndPeriod(1L);
#ifdef _WIN64
if (topLevelVectoredExceptionHandler != NULL) {
RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler);
topLevelVectoredExceptionHandler = NULL;
}
#endif
break;
default:
break;
@ -408,20 +398,14 @@ static unsigned __stdcall java_start(Thread* thread) {
}
if (UseVectoredExceptions) {
// If we are using vectored exception we don't need to set a SEH
thread->run();
}
else {
// Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
__try {
thread->run();
} __except(topLevelExceptionFilter(
(_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
// Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
__try {
thread->run();
} __except(topLevelExceptionFilter(
(_EXCEPTION_POINTERS*)_exception_info())) {
// Nothing to do.
}
// One less thread is executing
@ -2489,16 +2473,6 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
#endif
#ifdef _WIN64
// Windows will sometimes generate an access violation
// when we call malloc. Since we use VectoredExceptions
// on 64 bit platforms, we see this exception. We must
// pass this exception on so Windows can recover.
// We check to see if the pc of the fault is in NTDLL.DLL
// if so, we pass control on to Windows for handling.
if (UseVectoredExceptions && _addr_in_ntdll(pc)) return EXCEPTION_CONTINUE_SEARCH;
#endif
// Stack overflow or null pointer exception in native code.
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
@ -2527,30 +2501,8 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
}
if (exception_code != EXCEPTION_BREAKPOINT) {
#ifndef _WIN64
report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
#else
// Itanium Windows uses a VectoredExceptionHandler
// Which means that C++ programatic exception handlers (try/except)
// will get here. Continue the search for the right except block if
// the exception code is not a fatal code.
switch ( exception_code ) {
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_STACK_OVERFLOW:
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_ILLEGAL_INSTRUCTION_2:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_UNCAUGHT_CXX_EXCEPTION:
{ report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord,
exceptionInfo->ContextRecord);
}
break;
default:
break;
}
#endif
}
return EXCEPTION_CONTINUE_SEARCH;
}
@ -3706,18 +3658,6 @@ jint os::init_2(void) {
// Setup Windows Exceptions
// On Itanium systems, Structured Exception Handling does not
// work since stack frames must be walkable by the OS. Since
// much of our code is dynamically generated, and we do not have
// proper unwind .xdata sections, the system simply exits
// rather than delivering the exception. To work around
// this we use VectorExceptions instead.
#ifdef _WIN64
if (UseVectoredExceptions) {
topLevelVectoredExceptionHandler = AddVectoredExceptionHandler( 1, topLevelExceptionFilter);
}
#endif
// for debugging float code generation bugs
if (ForceFloatExceptions) {
#ifndef _WIN64

View File

@ -25,10 +25,6 @@
#ifndef OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
#ifndef _ALLBSD_SOURCE
#include <byteswap.h>
#endif
#ifdef __APPLE__
#include <libkern/OSByteOrder.h>
#endif

View File

@ -48,7 +48,5 @@ define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP

View File

@ -76,7 +76,7 @@
# include <ucontext.h>
#endif
#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
#if !defined(__APPLE__) && !defined(__NetBSD__)
# include <pthread_np.h>
#endif
@ -489,23 +489,6 @@ JVM_handle_bsd_signal(int sig,
// to handle_unexpected_exception way down below.
thread->disable_stack_red_zone();
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
#ifndef _ALLBSD_SOURCE
} else {
// Accessing stack address below sp may cause SEGV if current
// thread has MAP_GROWSDOWN stack. This should only happen when
// current thread was created by user code with MAP_GROWSDOWN flag
// and then attached to VM. See notes in os_bsd.cpp.
if (thread->osthread()->expanding_stack() == 0) {
thread->osthread()->set_expanding_stack();
if (os::Bsd::manually_expand_stack(thread, addr)) {
thread->osthread()->clear_expanding_stack();
return 1;
}
thread->osthread()->clear_expanding_stack();
} else {
fatal("recursive segv. expanding stack.");
}
#endif
}
}
}
@ -744,61 +727,21 @@ JVM_handle_bsd_signal(int sig,
ShouldNotReachHere();
}
#ifdef _ALLBSD_SOURCE
// From solaris_i486.s ported to bsd_i486.s
extern "C" void fixcw();
#endif
void os::Bsd::init_thread_fpu_state(void) {
#ifndef AMD64
# ifdef _ALLBSD_SOURCE
// Set fpu to 53 bit precision. This happens too early to use a stub.
fixcw();
# else
// set fpu to 53 bit precision
set_fpu_control_word(0x27f);
# endif
#endif // !AMD64
}
#ifndef _ALLBSD_SOURCE
int os::Bsd::get_fpu_control_word(void) {
#ifdef AMD64
return 0;
#else
int fpu_control;
_FPU_GETCW(fpu_control);
return fpu_control & 0xffff;
#endif // AMD64
}
void os::Bsd::set_fpu_control_word(int fpu_control) {
#ifndef AMD64
_FPU_SETCW(fpu_control);
#endif // !AMD64
}
#endif
// Check that the bsd kernel version is 2.4 or higher since earlier
// versions do not support SSE without patches.
bool os::supports_sse() {
#if defined(AMD64) || defined(_ALLBSD_SOURCE)
return true;
#else
struct utsname uts;
if( uname(&uts) != 0 ) return false; // uname fails?
char *minor_string;
int major = strtol(uts.release,&minor_string,10);
int minor = strtol(minor_string+1,NULL,10);
bool result = (major > 2 || (major==2 && minor >= 4));
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
tty->print("OS version is %d.%d, which %s support SSE/SSE2\n",
major,minor, result ? "DOES" : "does NOT");
}
#endif
return result;
#endif // AMD64
}
bool os::is_allocatable(size_t bytes) {
@ -836,46 +779,7 @@ size_t os::Bsd::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
#endif
#ifdef _ALLBSD_SOURCE
bool os::Bsd::supports_variable_stack_size() { return true; }
#else
// Test if pthread library can support variable thread stack size. BsdThreads
// in fixed stack mode allocates 2M fixed slot for each thread. BsdThreads
// in floating stack mode and NPTL support variable stack size.
bool os::Bsd::supports_variable_stack_size() {
if (os::Bsd::is_NPTL()) {
// NPTL, yes
return true;
} else {
// Note: We can't control default stack size when creating a thread.
// If we use non-default stack size (pthread_attr_setstacksize), both
// floating stack and non-floating stack BsdThreads will return the
// same value. This makes it impossible to implement this function by
// detecting thread stack size directly.
//
// An alternative approach is to check %gs. Fixed-stack BsdThreads
// do not use %gs, so its value is 0. Floating-stack BsdThreads use
// %gs (either as LDT selector or GDT selector, depending on kernel)
// to access thread specific data.
//
// Note that %gs is a reserved glibc register since early 2001, so
// applications are not allowed to change its value (Ulrich Drepper from
// Redhat confirmed that all known offenders have been modified to use
// either %fs or TSD). In the worst case scenario, when VM is embedded in
// a native application that plays with %gs, we might see non-zero %gs
// even BsdThreads is running in fixed stack mode. As the result, we'll
// return true and skip _thread_safety_check(), so we may not be able to
// detect stack-heap collisions. But otherwise it's harmless.
//
#ifdef __GNUC__
return (GET_GS() != 0);
#else
return false;
#endif
}
}
#endif
#endif // AMD64
// return default stack size for thr_type
@ -943,7 +847,7 @@ static void current_stack_region(address * bottom, size_t * size) {
*bottom = (address)((char *)ss.ss_sp - ss.ss_size);
*size = ss.ss_size;
#elif defined(_ALLBSD_SOURCE)
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
@ -963,33 +867,6 @@ static void current_stack_region(address * bottom, size_t * size) {
}
pthread_attr_destroy(&attr);
#else
if (os::Bsd::is_initial_thread()) {
// initial thread needs special handling because pthread_getattr_np()
// may return bogus value.
*bottom = os::Bsd::initial_thread_stack_bottom();
*size = os::Bsd::initial_thread_stack_size();
} else {
pthread_attr_t attr;
int rslt = pthread_getattr_np(pthread_self(), &attr);
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0) {
if (rslt == ENOMEM) {
vm_exit_out_of_memory(0, "pthread_getattr_np");
} else {
fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
}
}
if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
fatal("Can not locate current stack attributes!");
}
pthread_attr_destroy(&attr);
}
#endif
assert(os::current_stack_pointer() >= *bottom &&
os::current_stack_pointer() < *bottom + *size, "just checking");

View File

@ -41,7 +41,6 @@ define_pd_global(intx, VMThreadStackSize, 512);
define_pd_global(intx, CompilerThreadStackSize, 0);
define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
define_pd_global(bool, UseVectoredExceptions, false);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);

View File

@ -23,7 +23,7 @@
*
*/
#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
#if !defined(__APPLE__) && !defined(__NetBSD__)
#include <pthread.h>
# include <pthread_np.h> /* For pthread_attr_get_np */
#endif
@ -178,26 +178,6 @@ JVM_handle_bsd_signal(int sig,
thread->disable_stack_red_zone();
ShouldNotCallThis();
}
#ifndef _ALLBSD_SOURCE
else {
// Accessing stack address below sp may cause SEGV if
// current thread has MAP_GROWSDOWN stack. This should
// only happen when current thread was created by user
// code with MAP_GROWSDOWN flag and then attached to VM.
// See notes in os_bsd.cpp.
if (thread->osthread()->expanding_stack() == 0) {
thread->osthread()->set_expanding_stack();
if (os::Bsd::manually_expand_stack(thread, addr)) {
thread->osthread()->clear_expanding_stack();
return true;
}
thread->osthread()->clear_expanding_stack();
}
else {
fatal("recursive segv. expanding stack.");
}
}
#endif
}
}
@ -266,16 +246,6 @@ void os::Bsd::init_thread_fpu_state(void) {
// Nothing to do
}
#ifndef _ALLBSD_SOURCE
int os::Bsd::get_fpu_control_word() {
ShouldNotCallThis();
}
void os::Bsd::set_fpu_control_word(int fpu) {
ShouldNotCallThis();
}
#endif
bool os::is_allocatable(size_t bytes) {
#ifdef _LP64
return true;
@ -339,7 +309,7 @@ static void current_stack_region(address *bottom, size_t *size) {
stack_top = (address) ss.ss_sp;
stack_bytes = ss.ss_size;
stack_bottom = stack_top - stack_bytes;
#elif defined(_ALLBSD_SOURCE)
#else
pthread_attr_t attr;
int rslt = pthread_attr_init(&attr);
@ -362,67 +332,6 @@ static void current_stack_region(address *bottom, size_t *size) {
pthread_attr_destroy(&attr);
stack_top = stack_bottom + stack_bytes;
#else /* Linux */
pthread_attr_t attr;
int res = pthread_getattr_np(pthread_self(), &attr);
if (res != 0) {
if (res == ENOMEM) {
vm_exit_out_of_memory(0, "pthread_getattr_np");
}
else {
fatal(err_msg("pthread_getattr_np failed with errno = " INT32_FORMAT,
res));
}
}
res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
if (res != 0) {
fatal(err_msg("pthread_attr_getstack failed with errno = " INT32_FORMAT,
res));
}
stack_top = stack_bottom + stack_bytes;
// The block of memory returned by pthread_attr_getstack() includes
// guard pages where present. We need to trim these off.
size_t page_bytes = os::Bsd::page_size();
assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
size_t guard_bytes;
res = pthread_attr_getguardsize(&attr, &guard_bytes);
if (res != 0) {
fatal(err_msg(
"pthread_attr_getguardsize failed with errno = " INT32_FORMAT, res));
}
int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes;
assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
#ifdef IA64
// IA64 has two stacks sharing the same area of memory, a normal
// stack growing downwards and a register stack growing upwards.
// Guard pages, if present, are in the centre. This code splits
// the stack in two even without guard pages, though in theory
// there's nothing to stop us allocating more to the normal stack
// or more to the register stack if one or the other were found
// to grow faster.
int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes;
stack_bottom += (total_pages - guard_pages) / 2 * page_bytes;
#endif // IA64
stack_bottom += guard_bytes;
pthread_attr_destroy(&attr);
// The initial thread has a growable stack, and the size reported
// by pthread_attr_getstack is the maximum size it could possibly
// be given what currently mapped. This can be huge, so we cap it.
if (os::Bsd::is_initial_thread()) {
stack_bytes = stack_top - stack_bottom;
if (stack_bytes > JavaThread::stack_size_at_create())
stack_bytes = JavaThread::stack_size_at_create();
stack_bottom = stack_top - stack_bytes;
}
#endif
assert(os::current_stack_pointer() >= stack_bottom, "should do");

View File

@ -35,7 +35,5 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_LINUX_SPARC_VM_GLOBALS_LINUX_SPARC_HPP

View File

@ -46,7 +46,5 @@ define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx,HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP

View File

@ -41,7 +41,6 @@ define_pd_global(intx, VMThreadStackSize, 512);
define_pd_global(intx, CompilerThreadStackSize, 0);
define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
define_pd_global(bool, UseVectoredExceptions, false);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);

View File

@ -39,8 +39,6 @@ define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G);
#else
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
#endif
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);

View File

@ -45,7 +45,5 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx,HeapBaseMinAddress, 256*M);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP

View File

@ -47,7 +47,5 @@ define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
// Used on 64 bit platforms for UseCompressedOops base address or CDS
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
#endif // OS_CPU_WINDOWS_X86_VM_GLOBALS_WINDOWS_X86_HPP

View File

@ -175,9 +175,6 @@ bool os::register_code_area(char *low, char *high) {
PRUNTIME_FUNCTION prt;
PUNWIND_INFO_EH_ONLY punwind;
// If we are using Vectored Exceptions we don't need this registration
if (UseVectoredExceptions) return true;
BufferBlob* blob = BufferBlob::create("CodeCache Exception Handler", sizeof(DynamicCodeData));
CodeBuffer cb(blob);
MacroAssembler* masm = new MacroAssembler(&cb);

View File

@ -758,7 +758,7 @@ void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
}
}
if (dest->blob() == NULL) {
if (dest->blob() == NULL && dest_filled != NULL) {
// Destination is a final resting place, not just another buffer.
// Normalize uninitialized bytes in the final padding.
Copy::fill_to_bytes(dest_filled, dest_end - dest_filled,

View File

@ -115,6 +115,7 @@
/* Java runtime version access */ \
template(sun_misc_Version, "sun/misc/Version") \
template(java_runtime_name_name, "java_runtime_name") \
template(java_runtime_version_name, "java_runtime_version") \
\
/* class file format tags */ \
template(tag_source_file, "SourceFile") \

View File

@ -320,6 +320,7 @@ class AbstractInterpreterGenerator: public StackObj {
void bang_stack_shadow_pages(bool native_call);
void generate_all();
void initialize_method_handle_entries();
public:
AbstractInterpreterGenerator(StubQueue* _code);

View File

@ -235,10 +235,6 @@
#endif
#endif
// JavaStack Implementation
#define MORE_STACK(count) \
(topOfStack -= ((count) * Interpreter::stackElementWords))
#define UPDATE_PC(opsize) {pc += opsize; }
/*
@ -575,7 +571,7 @@ BytecodeInterpreter::run(interpreterState istate) {
/* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer,
/* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xE8 */ &&opc_invokehandle,&&opc_default, &&opc_default, &&opc_default,
/* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default,
@ -1773,7 +1769,7 @@ run:
oop obj;
if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
Klass* k = (Klass*) cache->f1();
Klass* k = cache->f1_as_klass();
obj = k->java_mirror();
MORE_STACK(1); // Assume single slot push
} else {
@ -1885,7 +1881,7 @@ run:
--count;
}
if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
Klass* k = (Klass*) cache->f1();
Klass* k = cache->f1_as_klass();
obj = k->java_mirror();
} else {
--count;
@ -2190,6 +2186,7 @@ run:
}
CASE(_invokedynamic): {
if (!EnableInvokeDynamic) {
// We should not encounter this bytecode if !EnableInvokeDynamic.
// The verifier will stop it. However, if we get past the verifier,
@ -2199,30 +2196,68 @@ run:
ShouldNotReachHere();
}
int index = Bytes::get_native_u4(pc+1);
u4 index = Bytes::get_native_u4(pc+1);
ConstantPoolCacheEntry* cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index);
// We are resolved if the resolved_references field contains a non-null object (CallSite, etc.)
// This kind of CP cache entry does not need to match the flags byte, because
// there is a 1-1 relation between bytecode type and CP entry type.
ConstantPool* constants = METHOD->constants();
oop result = constants->resolved_references()->obj_at(index);
if (result == NULL) {
if (! cache->is_resolved((Bytecodes::Code) opcode)) {
CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
handle_exception);
result = THREAD->vm_result();
cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index);
}
VERIFY_OOP(result);
oop method_handle = java_lang_invoke_CallSite::target(result);
CHECK_NULL(method_handle);
Method* method = cache->f1_as_method();
VERIFY_OOP(method);
istate->set_msg(call_method_handle);
istate->set_callee((Method*) method_handle);
if (cache->has_appendix()) {
ConstantPool* constants = METHOD->constants();
SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0);
MORE_STACK(1);
}
istate->set_msg(call_method);
istate->set_callee(method);
istate->set_callee_entry_point(method->from_interpreted_entry());
istate->set_bcp_advance(5);
UPDATE_PC_AND_RETURN(0); // I'll be back...
}
CASE(_invokehandle): {
if (!EnableInvokeDynamic) {
ShouldNotReachHere();
}
u2 index = Bytes::get_native_u2(pc+1);
ConstantPoolCacheEntry* cache = cp->entry_at(index);
if (! cache->is_resolved((Bytecodes::Code) opcode)) {
CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD),
handle_exception);
cache = cp->entry_at(index);
}
Method* method = cache->f1_as_method();
VERIFY_OOP(method);
if (cache->has_appendix()) {
ConstantPool* constants = METHOD->constants();
SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0);
MORE_STACK(1);
}
istate->set_msg(call_method);
istate->set_callee(method);
istate->set_callee_entry_point(method->from_interpreted_entry());
istate->set_bcp_advance(3);
UPDATE_PC_AND_RETURN(0); // I'll be back...
}
CASE(_invokeinterface): {
u2 index = Bytes::get_native_u2(pc+1);

View File

@ -50,6 +50,10 @@
#ifdef CC_INTERP
// JavaStack Implementation
#define MORE_STACK(count) \
(topOfStack -= ((count) * Interpreter::stackElementWords))
// CVM definitions find hotspot equivalents...
union VMJavaVal64 {
@ -107,7 +111,6 @@ public:
rethrow_exception, // unwinding and throwing exception
// requests to frame manager from C++ interpreter
call_method, // request for new frame from interpreter, manager responds with method_entry
call_method_handle, // like the above, except the callee is a method handle
return_from_method, // request from interpreter to unwind, manager responds with method_continue
more_monitors, // need a new monitor
throwing_exception, // unwind stack and rethrow

View File

@ -117,7 +117,6 @@ void CppInterpreterGenerator::generate_all() {
method_entry(empty);
method_entry(accessor);
method_entry(abstract);
method_entry(method_handle);
method_entry(java_lang_math_sin );
method_entry(java_lang_math_cos );
method_entry(java_lang_math_tan );
@ -125,7 +124,12 @@ void CppInterpreterGenerator::generate_all() {
method_entry(java_lang_math_sqrt );
method_entry(java_lang_math_log );
method_entry(java_lang_math_log10 );
method_entry(java_lang_math_pow );
method_entry(java_lang_math_exp );
method_entry(java_lang_ref_reference_get);
initialize_method_handle_entries();
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
method_entry(native);
method_entry(native_synchronized);

View File

@ -464,3 +464,11 @@ void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
}
}
}
void AbstractInterpreterGenerator::initialize_method_handle_entries() {
// method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
}
}

View File

@ -373,11 +373,7 @@ void TemplateInterpreterGenerator::generate_all() {
method_entry(java_lang_math_pow )
method_entry(java_lang_ref_reference_get)
// method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
}
initialize_method_handle_entries();
// all native method kinds (must be one contiguous block)
Interpreter::_native_entry_begin = Interpreter::code()->code_end();

View File

@ -742,6 +742,8 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
uint gc_count = 0;
uint full_gc_count = 0;
assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
do {
MetaWord* result = NULL;
if (GC_locker::is_active_and_needs_gc()) {
@ -756,7 +758,6 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
}
JavaThread* jthr = JavaThread::current();
if (!jthr->in_critical()) {
MutexUnlocker mul(Heap_lock);
// Wait for JNI critical section to be exited
GC_locker::stall_until_clear();
// The GC invoked by the last thread leaving the critical

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
<!--
Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2002, 2012, Oracle and/or its affiliates. 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
@ -358,7 +358,7 @@
<specification label="JVM(TM) Tool Interface"
majorversion="1"
minorversion="2"
microversion="1">
microversion="2">
<title subtitle="Version">
<tm>JVM</tm> Tool Interface
</title>
@ -405,7 +405,7 @@
interfaces are more appropriate than <jvmti/> for many tools.
For more information on the Java Platform Debugger Architecture,
see the
<externallink id="http://java.sun.com/products/jpda/">Java
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html">Java
Platform Debugger Architecture website</externallink>.
</intro>
@ -693,7 +693,7 @@ Agent_OnUnload(JavaVM *vm)</example>
An agent creates a <jvmti/> environment
by passing a <jvmti/> version
as the interface ID to the JNI Invocation API function
<externallink id="http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#GetEnv"><code>GetEnv</code></externallink>.
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#GetEnv"><code>GetEnv</code></externallink>.
See <internallink id="jvmtiEnvAccess">Accessing <jvmti/> Functions</internallink>
for more details on the creation and use of
<jvmti/> environments.
@ -797,7 +797,7 @@ Agent_OnUnload(JavaVM *vm)</example>
Modified UTF-8 differs
from standard UTF-8 in the representation of supplementary characters
and of the null character. See the
<externallink id="http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp16542">
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html#wp16542">
Modified UTF-8 Strings</externallink>
section of the JNI specification for details.
</intro>
@ -827,7 +827,7 @@ Agent_OnUnload(JavaVM *vm)</example>
by calling <jvmti/> functions.
Access to <jvmti/> functions is by use of an interface pointer
in the same manner as
<externallink id="http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.html">Java
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html">Java
Native Interface (JNI) functions</externallink> are accessed.
The <jvmti/> interface pointer is called the
<i>environment pointer</i>.
@ -919,7 +919,7 @@ jvmtiEnv *jvmti;
local references--these local references are created
during the <jvmti/> call.
Local references are a resource that must be managed (see the
<externallink id="http://java.sun.com/javase/6/docs/guide/jni/spec/functions.html#wp18654">JNI Documentation</externallink>).
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp18654">JNI Documentation</externallink>).
When threads return from native code all local references
are freed. Note that some threads, including typical
agent threads, will never return from native code.
@ -954,7 +954,7 @@ jvmtiEnv *jvmti;
<jvmti/> function.
See the
<externallink
id="http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp770"
id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp770"
>Java Exceptions</externallink>
section of the JNI specification for information on handling exceptions.
</intro>
@ -2024,7 +2024,7 @@ jvmtiEnv *jvmti;
<p/>
Upon execution of <code>proc</code>, the new thread will be attached to the
VM--see the JNI documentation on
<externallink id="http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#wp1060"
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#wp1060"
>Attaching to the VM</externallink>.
</description>
<origin>jvmdiClone</origin>
@ -4010,7 +4010,7 @@ class C2 extends C1 implements I2 {
</inptr>
<description>
Details about the reference.
Set when the <paramlink id="reference_kind"/> is
Set when the <datalink id="jvmtiHeapReferenceCallback.reference_kind">reference_kind</datalink> is
<datalink id="JVMTI_HEAP_REFERENCE_FIELD"/>,
<datalink id="JVMTI_HEAP_REFERENCE_STATIC_FIELD"/>,
<datalink id="JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT"/>,
@ -4378,7 +4378,7 @@ class C2 extends C1 implements I2 {
do not control which objects are visited but they do control which
objects and primitive values are reported by the callbacks.
For example, if the only callback that was set is
<paramlink id="array_primitive_value_callback"/> and <code>klass</code>
<fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/> and <code>klass</code>
is set to the array of bytes class, then only arrays of byte will be
reported.
The table below summarizes this:
@ -4414,7 +4414,7 @@ class C2 extends C1 implements I2 {
</tr>
<tr>
<th align="left">
<fieldlink id="object_reference_callback" struct="jvmtiHeapCallbacks"/>
<fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/>
in <paramlink id="callbacks"/> set
</th>
<td>
@ -4570,7 +4570,7 @@ class C2 extends C1 implements I2 {
do not control which objects are visited but they do control which
objects and primitive values are reported by the callbacks.
For example, if the only callback that was set is
<paramlink id="array_primitive_value_callback"/> and <code>klass</code>
<fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/> and <code>klass</code>
is set to the array of bytes class, then only arrays of byte will be
reported. The table below summarizes this (contrast this with
<functionlink id="FollowReferences"/>):
@ -4606,7 +4606,7 @@ class C2 extends C1 implements I2 {
</tr>
<tr>
<th align="left">
<fieldlink id="object_callback" struct="jvmtiHeapCallbacks"/>
<fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/>
in <paramlink id="callbacks"/> set
</th>
<td>
@ -6478,7 +6478,7 @@ class C2 extends C1 implements I2 {
<synopsis>Get Class Signature</synopsis>
<description>
For the class indicated by <code>klass</code>, return the
<externallink id="http://java.sun.com/javase/6/docs/guide/jni/spec/types.html#wp16432">JNI
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html#wp16432">JNI
type signature</externallink>
and the generic signature of the class.
For example, <code>java.util.List</code> is <code>"Ljava/util/List;"</code>
@ -8763,7 +8763,7 @@ method(wrapped_foo) -> nativeImplementation(foo)</example>
Provides the ability to intercept and resend
Java Native Interface (JNI) function calls
by manipulating the JNI function table.
See <externallink id="http://java.sun.com/javase/6/docs/guide/jni/spec/functions.html">JNI
See <externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html">JNI
Functions</externallink> in the <i>Java Native Interface Specification</i>.
<p/>
The following example illustrates intercepting the
@ -10446,7 +10446,7 @@ myInit() {
for a class. The segment is typically a directory or JAR file.
<p/>
In the live phase the <paramlink id="segment"/> may be used to specify any platform-dependent
path to a <externallink id="http://java.sun.com/javase/6/docs/guide/jar/jar.html">
path to a <externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html">
JAR file</externallink>. The agent should take care that the JAR file does not
contain any classes or resources other than those to be defined by the bootstrap
class loader for the purposes of instrumentation.
@ -10494,7 +10494,7 @@ myInit() {
for a class. The segment is typically a directory or JAR file.
<p/>
In the live phase the <paramlink id="segment"/> is a platform-dependent path to a <externallink
id="http://java.sun.com/javase/6/docs/guide/jar/jar.html">JAR file</externallink> to be
id="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html">JAR file</externallink> to be
searched after the system class loader unsuccessfully searches for a class. The agent should
take care that the JAR file does not contain any classes or resources other than those to be
defined by the system class loader for the purposes of instrumentation.
@ -13128,6 +13128,12 @@ myInit() {
Unsigned 8 bits.
</description>
</basetype>
<basetype id="jchar">
<description>
Holds a Java programming language <code>char</code>.
Unsigned 16 bits.
</description>
</basetype>
<basetype id="jint">
<description>
Holds a Java programming language <code>int</code>.
@ -13285,7 +13291,7 @@ typedef void (JNICALL *jvmtiEventVMInit)
<description>
Typedef for the JNI function table <code>JNINativeInterface</code>
defined in the
<externallink id="http://java.sun.com/javase/6/docs/guide/jni/spec/functions.html#wp23720">JNI Specification</externallink>.
<externallink id="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp23720">JNI Specification</externallink>.
The JNI reference implementation defines this with an underscore.
</description>
</basetype>
@ -14252,6 +14258,9 @@ typedef void (JNICALL *jvmtiEventVMInit)
<change date="6 August 2006" version="1.1.102">
Add ResourceExhaustedEvent.
</change>
<change date="11 October 2012" version="1.2.2">
Fixed the "HTTP" and "Missing Anchor" errors reported by the LinkCheck tool.
</change>
</changehistory>
</specification>

View File

@ -69,7 +69,7 @@ class JvmtiEnvBase : public CHeapObj<mtInternal> {
enum {
JDK15_JVMTI_VERSION = JVMTI_VERSION_1_0 + 33, /* version: 1.0.33 */
JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102, /* version: 1.1.102 */
JDK17_JVMTI_VERSION = JVMTI_VERSION_1_2 + 1 /* version: 1.2.1 */
JDK17_JVMTI_VERSION = JVMTI_VERSION_1_2 + 2 /* version: 1.2.2 */
};
static jvmtiPhase get_phase() { return _phase; }

View File

@ -257,6 +257,7 @@ static ObsoleteFlag obsolete_jvm_flags[] = {
{ "MaxPermHeapExpansion", JDK_Version::jdk(8), JDK_Version::jdk(9) },
{ "CMSRevisitStackSize", JDK_Version::jdk(8), JDK_Version::jdk(9) },
{ "PrintRevisitStats", JDK_Version::jdk(8), JDK_Version::jdk(9) },
{ "UseVectoredExceptions", JDK_Version::jdk(8), JDK_Version::jdk(9) },
#ifdef PRODUCT
{ "DesiredMethodLimit",
JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
@ -2568,7 +2569,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
FLAG_SET_CMDLINE(uintx, MaxNewSize, NewSize);
}
#ifndef _ALLBSD_SOURCE // UseLargePages is not yet supported on BSD.
FLAG_SET_DEFAULT(UseLargePages, true);
#endif
// Increase some data structure sizes for efficiency
FLAG_SET_CMDLINE(uintx, BaseFootPrintEstimate, MaxHeapSize);
@ -3133,6 +3136,10 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
UNSUPPORTED_OPTION(UseG1GC, "G1 GC");
#endif
#ifdef _ALLBSD_SOURCE // UseLargePages is not yet supported on BSD.
UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages");
#endif
#if !INCLUDE_ALTERNATE_GCS
if (UseParallelGC) {
warning("Parallel GC is not supported in this VM. Using Serial GC.");

View File

@ -857,9 +857,6 @@ class CommandLineFlags {
develop(bool, BreakAtWarning, false, \
"Execute breakpoint upon encountering VM warning") \
\
product_pd(bool, UseVectoredExceptions, \
"Temp Flag - Use Vectored Exceptions rather than SEH (Windows Only)") \
\
develop(bool, TraceVMOperation, false, \
"Trace vm operations") \
\

View File

@ -688,6 +688,7 @@ void vm_shutdown_during_initialization(const char* error, const char* message) {
JDK_Version JDK_Version::_current;
const char* JDK_Version::_runtime_name;
const char* JDK_Version::_runtime_version;
void JDK_Version::initialize() {
jdk_version_info info;

View File

@ -75,6 +75,7 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC {
static JDK_Version _current;
static const char* _runtime_name;
static const char* _runtime_version;
// In this class, we promote the minor version of release to be the
// major version for releases >= 5 in anticipation of the JDK doing the
@ -189,6 +190,13 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC {
_runtime_name = name;
}
static const char* runtime_version() {
return _runtime_version;
}
static void set_runtime_version(const char* version) {
_runtime_version = version;
}
// Convenience methods for queries on the current major/minor version
static bool is_jdk12x_version() {
return current().compare_major(2) == 0;

View File

@ -1042,6 +1042,7 @@ static void call_initializeSystemClass(TRAPS) {
}
char java_runtime_name[128] = "";
char java_runtime_version[128] = "";
// extract the JRE name from sun.misc.Version.java_runtime_name
static const char* get_java_runtime_name(TRAPS) {
@ -1064,6 +1065,27 @@ static const char* get_java_runtime_name(TRAPS) {
}
}
// extract the JRE version from sun.misc.Version.java_runtime_version
static const char* get_java_runtime_version(TRAPS) {
Klass* k = SystemDictionary::find(vmSymbols::sun_misc_Version(),
Handle(), Handle(), CHECK_AND_CLEAR_NULL);
fieldDescriptor fd;
bool found = k != NULL &&
InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_version_name(),
vmSymbols::string_signature(), &fd);
if (found) {
oop name_oop = k->java_mirror()->obj_field(fd.offset());
if (name_oop == NULL)
return NULL;
const char* name = java_lang_String::as_utf8_string(name_oop,
java_runtime_version,
sizeof(java_runtime_version));
return name;
} else {
return NULL;
}
}
// General purpose hook into Java code, run once when the VM is initialized.
// The Java library method itself may be changed independently from the VM.
static void call_postVMInitHook(TRAPS) {
@ -3473,6 +3495,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
// get the Java runtime name after java.lang.System is initialized
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
} else {
warning("java.lang.System not initialized");
}

View File

@ -2474,7 +2474,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
/* frame */ \
/**********************/ \
\
X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset)) \
NOT_ZERO(X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))) \
declare_constant(frame::pc_return_offset) \
\
/*************/ \

View File

@ -282,6 +282,22 @@
#define NOT_WIN64(code) code
#endif
#if defined(ZERO)
#define ZERO_ONLY(code) code
#define NOT_ZERO(code)
#else
#define ZERO_ONLY(code)
#define NOT_ZERO(code) code
#endif
#if defined(SHARK)
#define SHARK_ONLY(code) code
#define NOT_SHARK(code)
#else
#define SHARK_ONLY(code)
#define NOT_SHARK(code) code
#endif
#if defined(IA32) || defined(AMD64)
#define X86
#define X86_ONLY(code) code

View File

@ -496,9 +496,7 @@ public:
}
}
bool steal_1_random(uint queue_num, int* seed, E& t);
bool steal_best_of_2(uint queue_num, int* seed, E& t);
bool steal_best_of_all(uint queue_num, int* seed, E& t);
void register_queue(uint i, T* q);
@ -537,46 +535,6 @@ GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
return false;
}
template<class T, MEMFLAGS F> bool
GenericTaskQueueSet<T, F>::steal_best_of_all(uint queue_num, int* seed, E& t) {
if (_n > 2) {
int best_k;
uint best_sz = 0;
for (uint k = 0; k < _n; k++) {
if (k == queue_num) continue;
uint sz = _queues[k]->size();
if (sz > best_sz) {
best_sz = sz;
best_k = k;
}
}
return best_sz > 0 && _queues[best_k]->pop_global(t);
} else if (_n == 2) {
// Just try the other one.
int k = (queue_num + 1) % 2;
return _queues[k]->pop_global(t);
} else {
assert(_n == 1, "can't be zero.");
return false;
}
}
template<class T, MEMFLAGS F> bool
GenericTaskQueueSet<T, F>::steal_1_random(uint queue_num, int* seed, E& t) {
if (_n > 2) {
uint k = queue_num;
while (k == queue_num) k = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
return _queues[2]->pop_global(t);
} else if (_n == 2) {
// Just try the other one.
int k = (queue_num + 1) % 2;
return _queues[k]->pop_global(t);
} else {
assert(_n == 1, "can't be zero.");
return false;
}
}
template<class T, MEMFLAGS F> bool
GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) {
if (_n > 2) {

View File

@ -453,7 +453,9 @@ void VMError::report(outputStream* st) {
JDK_Version::current().to_string(buf, sizeof(buf));
const char* runtime_name = JDK_Version::runtime_name() != NULL ?
JDK_Version::runtime_name() : "";
st->print_cr("# JRE version: %s (%s)", runtime_name, buf);
const char* runtime_version = JDK_Version::runtime_version() != NULL ?
JDK_Version::runtime_version() : "";
st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
st->print_cr("# Java VM: %s (%s %s %s %s)",
Abstract_VM_Version::vm_name(),
Abstract_VM_Version::vm_release(),