6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
Passing a null pointer to an InvokeDynamic function call should lead to a NullPointerException. Reviewed-by: kvn, never
This commit is contained in:
parent
dae3356905
commit
82e9e2b4af
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -37,8 +37,13 @@ static bool returns_to_call_stub(address return_pc) {
|
|||||||
|
|
||||||
enum /* platform_dependent_constants */ {
|
enum /* platform_dependent_constants */ {
|
||||||
// %%%%%%%% May be able to shrink this a lot
|
// %%%%%%%% May be able to shrink this a lot
|
||||||
code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
|
code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
|
||||||
code_size2 = 20000 // simply increase if too small (assembler will crash if too small)
|
code_size2 = 20000 // simply increase if too small (assembler will crash if too small)
|
||||||
|
};
|
||||||
|
|
||||||
|
// MethodHandles adapters
|
||||||
|
enum method_handles_platform_dependent_constants {
|
||||||
|
method_handles_adapters_code_size = 5000
|
||||||
};
|
};
|
||||||
|
|
||||||
class Sparc {
|
class Sparc {
|
||||||
|
@ -2276,16 +2276,6 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// arraycopy stubs used by compilers
|
// arraycopy stubs used by compilers
|
||||||
generate_arraycopy_stubs();
|
generate_arraycopy_stubs();
|
||||||
|
|
||||||
// generic method handle stubs
|
|
||||||
if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
|
|
||||||
for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
|
|
||||||
ek < MethodHandles::_EK_LIMIT;
|
|
||||||
ek = MethodHandles::EntryKind(1 + (int)ek)) {
|
|
||||||
StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
|
|
||||||
MethodHandles::generate_method_handle_stub(_masm, ek);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_math_stubs();
|
generate_math_stubs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3009,16 +3009,6 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// arraycopy stubs used by compilers
|
// arraycopy stubs used by compilers
|
||||||
generate_arraycopy_stubs();
|
generate_arraycopy_stubs();
|
||||||
|
|
||||||
// generic method handle stubs
|
|
||||||
if (EnableMethodHandles && SystemDictionary::MethodHandle_klass() != NULL) {
|
|
||||||
for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
|
|
||||||
ek < MethodHandles::_EK_LIMIT;
|
|
||||||
ek = MethodHandles::EntryKind(1 + (int)ek)) {
|
|
||||||
StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
|
|
||||||
MethodHandles::generate_method_handle_stub(_masm, ek);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_math_stubs();
|
generate_math_stubs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,6 +31,11 @@ enum platform_dependent_constants {
|
|||||||
code_size2 = 22000 // simply increase if too small (assembler will crash if too small)
|
code_size2 = 22000 // simply increase if too small (assembler will crash if too small)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// MethodHandles adapters
|
||||||
|
enum method_handles_platform_dependent_constants {
|
||||||
|
method_handles_adapters_code_size = 5000
|
||||||
|
};
|
||||||
|
|
||||||
class x86 {
|
class x86 {
|
||||||
friend class StubGenerator;
|
friend class StubGenerator;
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,12 +28,14 @@
|
|||||||
|
|
||||||
static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; }
|
static bool returns_to_call_stub(address return_pc) { return return_pc == _call_stub_return_address; }
|
||||||
|
|
||||||
enum platform_dependent_constants
|
enum platform_dependent_constants {
|
||||||
{
|
code_size1 = 19000, // simply increase if too small (assembler will crash if too small)
|
||||||
code_size1 = 19000, // simply increase if too small (assembler will
|
code_size2 = 22000 // simply increase if too small (assembler will crash if too small)
|
||||||
// crash if too small)
|
};
|
||||||
code_size2 = 22000 // simply increase if too small (assembler will
|
|
||||||
// crash if too small)
|
// MethodHandles adapters
|
||||||
|
enum method_handles_platform_dependent_constants {
|
||||||
|
method_handles_adapters_code_size = 13000
|
||||||
};
|
};
|
||||||
|
|
||||||
class x86 {
|
class x86 {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -249,7 +249,6 @@ BufferBlob* BufferBlob::create(const char* name, int buffer_size) {
|
|||||||
size += round_to(buffer_size, oopSize);
|
size += round_to(buffer_size, oopSize);
|
||||||
assert(name != NULL, "must provide a name");
|
assert(name != NULL, "must provide a name");
|
||||||
{
|
{
|
||||||
|
|
||||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
blob = new (size) BufferBlob(name, size);
|
blob = new (size) BufferBlob(name, size);
|
||||||
}
|
}
|
||||||
@ -271,7 +270,6 @@ BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {
|
|||||||
unsigned int size = allocation_size(cb, sizeof(BufferBlob));
|
unsigned int size = allocation_size(cb, sizeof(BufferBlob));
|
||||||
assert(name != NULL, "must provide a name");
|
assert(name != NULL, "must provide a name");
|
||||||
{
|
{
|
||||||
|
|
||||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
blob = new (size) BufferBlob(name, size, cb);
|
blob = new (size) BufferBlob(name, size, cb);
|
||||||
}
|
}
|
||||||
@ -298,10 +296,48 @@ void BufferBlob::free( BufferBlob *blob ) {
|
|||||||
MemoryService::track_code_cache_memory_usage();
|
MemoryService::track_code_cache_memory_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferBlob::is_adapter_blob() const {
|
|
||||||
return (strcmp(AdapterHandlerEntry::name, name()) == 0);
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
// Implementation of AdapterBlob
|
||||||
|
|
||||||
|
AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
|
||||||
|
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
|
||||||
|
|
||||||
|
AdapterBlob* blob = NULL;
|
||||||
|
unsigned int size = allocation_size(cb, sizeof(AdapterBlob));
|
||||||
|
{
|
||||||
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
blob = new (size) AdapterBlob(size, cb);
|
||||||
|
}
|
||||||
|
// Track memory usage statistic after releasing CodeCache_lock
|
||||||
|
MemoryService::track_code_cache_memory_usage();
|
||||||
|
|
||||||
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
// Implementation of MethodHandlesAdapterBlob
|
||||||
|
|
||||||
|
MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {
|
||||||
|
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
|
||||||
|
|
||||||
|
MethodHandlesAdapterBlob* blob = NULL;
|
||||||
|
unsigned int size = sizeof(MethodHandlesAdapterBlob);
|
||||||
|
// align the size to CodeEntryAlignment
|
||||||
|
size = align_code_offset(size);
|
||||||
|
size += round_to(buffer_size, oopSize);
|
||||||
|
{
|
||||||
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
blob = new (size) MethodHandlesAdapterBlob(size);
|
||||||
|
}
|
||||||
|
// Track memory usage statistic after releasing CodeCache_lock
|
||||||
|
MemoryService::track_code_cache_memory_usage();
|
||||||
|
|
||||||
|
return blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
// Implementation of RuntimeStub
|
// Implementation of RuntimeStub
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -90,14 +90,15 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
// Typing
|
// Typing
|
||||||
virtual bool is_buffer_blob() const { return false; }
|
virtual bool is_buffer_blob() const { return false; }
|
||||||
virtual bool is_nmethod() const { return false; }
|
virtual bool is_nmethod() const { return false; }
|
||||||
virtual bool is_runtime_stub() const { return false; }
|
virtual bool is_runtime_stub() const { return false; }
|
||||||
virtual bool is_deoptimization_stub() const { return false; }
|
virtual bool is_deoptimization_stub() const { return false; }
|
||||||
virtual bool is_uncommon_trap_stub() const { return false; }
|
virtual bool is_uncommon_trap_stub() const { return false; }
|
||||||
virtual bool is_exception_stub() const { return false; }
|
virtual bool is_exception_stub() const { return false; }
|
||||||
virtual bool is_safepoint_stub() const { return false; }
|
virtual bool is_safepoint_stub() const { return false; }
|
||||||
virtual bool is_adapter_blob() const { return false; }
|
virtual bool is_adapter_blob() const { return false; }
|
||||||
|
virtual bool is_method_handles_adapter_blob() const { return false; }
|
||||||
|
|
||||||
virtual bool is_compiled_by_c2() const { return false; }
|
virtual bool is_compiled_by_c2() const { return false; }
|
||||||
virtual bool is_compiled_by_c1() const { return false; }
|
virtual bool is_compiled_by_c1() const { return false; }
|
||||||
@ -221,6 +222,9 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||||||
|
|
||||||
class BufferBlob: public CodeBlob {
|
class BufferBlob: public CodeBlob {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
|
friend class AdapterBlob;
|
||||||
|
friend class MethodHandlesAdapterBlob;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Creation support
|
// Creation support
|
||||||
BufferBlob(const char* name, int size);
|
BufferBlob(const char* name, int size);
|
||||||
@ -236,8 +240,7 @@ class BufferBlob: public CodeBlob {
|
|||||||
static void free(BufferBlob* buf);
|
static void free(BufferBlob* buf);
|
||||||
|
|
||||||
// Typing
|
// Typing
|
||||||
bool is_buffer_blob() const { return true; }
|
virtual bool is_buffer_blob() const { return true; }
|
||||||
bool is_adapter_blob() const;
|
|
||||||
|
|
||||||
// GC/Verification support
|
// GC/Verification support
|
||||||
void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
|
void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
|
||||||
@ -254,6 +257,40 @@ class BufferBlob: public CodeBlob {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
// AdapterBlob: used to hold C2I/I2C adapters
|
||||||
|
|
||||||
|
class AdapterBlob: public BufferBlob {
|
||||||
|
private:
|
||||||
|
AdapterBlob(int size) : BufferBlob("I2C/C2I adapters", size) {}
|
||||||
|
AdapterBlob(int size, CodeBuffer* cb) : BufferBlob("I2C/C2I adapters", size, cb) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Creation
|
||||||
|
static AdapterBlob* create(CodeBuffer* cb);
|
||||||
|
|
||||||
|
// Typing
|
||||||
|
virtual bool is_adapter_blob() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
// MethodHandlesAdapterBlob: used to hold MethodHandles adapters
|
||||||
|
|
||||||
|
class MethodHandlesAdapterBlob: public BufferBlob {
|
||||||
|
private:
|
||||||
|
MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {}
|
||||||
|
MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Creation
|
||||||
|
static MethodHandlesAdapterBlob* create(int buffer_size);
|
||||||
|
|
||||||
|
// Typing
|
||||||
|
virtual bool is_method_handles_adapter_blob() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
|
// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
|
||||||
|
|
||||||
|
@ -2017,6 +2017,7 @@ init.cpp handles.inline.hpp
|
|||||||
init.cpp icBuffer.hpp
|
init.cpp icBuffer.hpp
|
||||||
init.cpp icache.hpp
|
init.cpp icache.hpp
|
||||||
init.cpp init.hpp
|
init.cpp init.hpp
|
||||||
|
init.cpp methodHandles.hpp
|
||||||
init.cpp safepoint.hpp
|
init.cpp safepoint.hpp
|
||||||
init.cpp sharedRuntime.hpp
|
init.cpp sharedRuntime.hpp
|
||||||
init.cpp universe.hpp
|
init.cpp universe.hpp
|
||||||
@ -2871,6 +2872,7 @@ methodHandles.cpp methodHandles.hpp
|
|||||||
methodHandles.cpp oopFactory.hpp
|
methodHandles.cpp oopFactory.hpp
|
||||||
methodHandles.cpp reflection.hpp
|
methodHandles.cpp reflection.hpp
|
||||||
methodHandles.cpp signature.hpp
|
methodHandles.cpp signature.hpp
|
||||||
|
methodHandles.cpp stubRoutines.hpp
|
||||||
methodHandles.cpp symbolTable.hpp
|
methodHandles.cpp symbolTable.hpp
|
||||||
|
|
||||||
methodHandles_<arch>.cpp allocation.inline.hpp
|
methodHandles_<arch>.cpp allocation.inline.hpp
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -82,6 +82,10 @@ const char* MethodHandles::_entry_names[_EK_LIMIT+1] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Adapters.
|
||||||
|
MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
|
||||||
|
int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size;
|
||||||
|
|
||||||
jobject MethodHandles::_raise_exception_method;
|
jobject MethodHandles::_raise_exception_method;
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -95,6 +99,41 @@ bool MethodHandles::spot_check_entry_names() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MethodHandles::generate_adapters
|
||||||
|
//
|
||||||
|
void MethodHandles::generate_adapters() {
|
||||||
|
if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return;
|
||||||
|
|
||||||
|
assert(_adapter_code == NULL, "generate only once");
|
||||||
|
|
||||||
|
ResourceMark rm;
|
||||||
|
TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
|
||||||
|
_adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size);
|
||||||
|
if (_adapter_code == NULL)
|
||||||
|
vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters");
|
||||||
|
CodeBuffer code(_adapter_code->instructions_begin(), _adapter_code->instructions_size());
|
||||||
|
|
||||||
|
MethodHandlesAdapterGenerator g(&code);
|
||||||
|
g.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MethodHandlesAdapterGenerator::generate
|
||||||
|
//
|
||||||
|
void MethodHandlesAdapterGenerator::generate() {
|
||||||
|
// Generate generic method handle adapters.
|
||||||
|
for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
|
||||||
|
ek < MethodHandles::_EK_LIMIT;
|
||||||
|
ek = MethodHandles::EntryKind(1 + (int)ek)) {
|
||||||
|
StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
|
||||||
|
MethodHandles::generate_method_handle_stub(_masm, ek);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MethodHandles::set_enabled(bool z) {
|
void MethodHandles::set_enabled(bool z) {
|
||||||
if (_enabled != z) {
|
if (_enabled != z) {
|
||||||
guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
|
guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles");
|
||||||
|
@ -115,6 +115,10 @@ class MethodHandles: AllStatic {
|
|||||||
static const char* _entry_names[_EK_LIMIT+1];
|
static const char* _entry_names[_EK_LIMIT+1];
|
||||||
static jobject _raise_exception_method;
|
static jobject _raise_exception_method;
|
||||||
|
|
||||||
|
// Adapters.
|
||||||
|
static MethodHandlesAdapterBlob* _adapter_code;
|
||||||
|
static int _adapter_code_size;
|
||||||
|
|
||||||
static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; }
|
static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; }
|
||||||
static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; }
|
static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; }
|
||||||
|
|
||||||
@ -230,7 +234,10 @@ class MethodHandles: AllStatic {
|
|||||||
// bit values for suppress argument to expand_MemberName:
|
// bit values for suppress argument to expand_MemberName:
|
||||||
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
|
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
|
||||||
|
|
||||||
// called from InterpreterGenerator and StubGenerator
|
// Generate MethodHandles adapters.
|
||||||
|
static void generate_adapters();
|
||||||
|
|
||||||
|
// Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
|
||||||
static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
|
static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
|
||||||
static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
|
static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
|
||||||
|
|
||||||
@ -447,3 +454,14 @@ class MethodHandleEntry {
|
|||||||
|
|
||||||
address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); }
|
address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); }
|
||||||
address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }
|
address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MethodHandlesAdapterGenerator
|
||||||
|
//
|
||||||
|
class MethodHandlesAdapterGenerator : public StubCodeGenerator {
|
||||||
|
public:
|
||||||
|
MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code) {}
|
||||||
|
|
||||||
|
void generate();
|
||||||
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -118,6 +118,9 @@ jint init_globals() {
|
|||||||
javaClasses_init(); // must happen after vtable initialization
|
javaClasses_init(); // must happen after vtable initialization
|
||||||
stubRoutines_init2(); // note: StubRoutines need 2-phase init
|
stubRoutines_init2(); // note: StubRoutines need 2-phase init
|
||||||
|
|
||||||
|
// Generate MethodHandles adapters.
|
||||||
|
MethodHandles::generate_adapters();
|
||||||
|
|
||||||
// Although we'd like to, we can't easily do a heap verify
|
// Although we'd like to, we can't easily do a heap verify
|
||||||
// here because the main thread isn't yet a JavaThread, so
|
// here because the main thread isn't yet a JavaThread, so
|
||||||
// its TLAB may not be made parseable from the usual interfaces.
|
// its TLAB may not be made parseable from the usual interfaces.
|
||||||
|
@ -582,7 +582,7 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
|
|||||||
// 3. Implict null exception in nmethod
|
// 3. Implict null exception in nmethod
|
||||||
|
|
||||||
if (!cb->is_nmethod()) {
|
if (!cb->is_nmethod()) {
|
||||||
guarantee(cb->is_adapter_blob(),
|
guarantee(cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(),
|
||||||
"exception happened outside interpreter, nmethods and vtable stubs (1)");
|
"exception happened outside interpreter, nmethods and vtable stubs (1)");
|
||||||
// There is no handler here, so we will simply unwind.
|
// There is no handler here, so we will simply unwind.
|
||||||
return StubRoutines::throw_NullPointerException_at_call_entry();
|
return StubRoutines::throw_NullPointerException_at_call_entry();
|
||||||
@ -2079,7 +2079,6 @@ class AdapterHandlerTableIterator : public StackObj {
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Implementation of AdapterHandlerLibrary
|
// Implementation of AdapterHandlerLibrary
|
||||||
const char* AdapterHandlerEntry::name = "I2C/C2I adapters";
|
|
||||||
AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL;
|
AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL;
|
||||||
AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL;
|
AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL;
|
||||||
const int AdapterHandlerLibrary_size = 16*K;
|
const int AdapterHandlerLibrary_size = 16*K;
|
||||||
@ -2131,7 +2130,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
NOT_PRODUCT(int code_size);
|
NOT_PRODUCT(int code_size);
|
||||||
BufferBlob *B = NULL;
|
AdapterBlob* B = NULL;
|
||||||
AdapterHandlerEntry* entry = NULL;
|
AdapterHandlerEntry* entry = NULL;
|
||||||
AdapterFingerPrint* fingerprint = NULL;
|
AdapterFingerPrint* fingerprint = NULL;
|
||||||
{
|
{
|
||||||
@ -2181,7 +2180,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
|
|
||||||
// Create I2C & C2I handlers
|
// Create I2C & C2I handlers
|
||||||
|
|
||||||
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
|
CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
|
||||||
short buffer_locs[20];
|
short buffer_locs[20];
|
||||||
@ -2210,7 +2209,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
B = BufferBlob::create(AdapterHandlerEntry::name, &buffer);
|
B = AdapterBlob::create(&buffer);
|
||||||
NOT_PRODUCT(code_size = buffer.code_size());
|
NOT_PRODUCT(code_size = buffer.code_size());
|
||||||
}
|
}
|
||||||
if (B == NULL) {
|
if (B == NULL) {
|
||||||
@ -2242,7 +2241,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||||||
jio_snprintf(blob_id,
|
jio_snprintf(blob_id,
|
||||||
sizeof(blob_id),
|
sizeof(blob_id),
|
||||||
"%s(%s)@" PTR_FORMAT,
|
"%s(%s)@" PTR_FORMAT,
|
||||||
AdapterHandlerEntry::name,
|
B->name(),
|
||||||
fingerprint->as_string(),
|
fingerprint->as_string(),
|
||||||
B->instructions_begin());
|
B->instructions_begin());
|
||||||
VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
|
VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
|
||||||
|
@ -567,9 +567,6 @@ class AdapterHandlerEntry : public BasicHashtableEntry {
|
|||||||
AdapterHandlerEntry();
|
AdapterHandlerEntry();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The name we give all buffer blobs
|
|
||||||
static const char* name;
|
|
||||||
|
|
||||||
address get_i2c_entry() { return _i2c_entry; }
|
address get_i2c_entry() { return _i2c_entry; }
|
||||||
address get_c2i_entry() { return _c2i_entry; }
|
address get_c2i_entry() { return _c2i_entry; }
|
||||||
address get_c2i_unverified_entry() { return _c2i_unverified_entry; }
|
address get_c2i_unverified_entry() { return _c2i_unverified_entry; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user