forked from pool/java-1_8_0-openjdk
224 lines
8.6 KiB
Diff
224 lines
8.6 KiB
Diff
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/codeBlob.cpp 2018-09-18 10:17:46.065548902 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/codeBlob.cpp 2018-09-18 10:18:04.537649500 +0200
|
|
@@ -292,6 +292,28 @@
|
|
return blob;
|
|
}
|
|
|
|
+VtableBlob::VtableBlob(const char* name, int size) :
|
|
+ BufferBlob(name, size) {
|
|
+}
|
|
+
|
|
+VtableBlob* VtableBlob::create(const char* name, int buffer_size) {
|
|
+ ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
|
|
+
|
|
+ VtableBlob* blob = NULL;
|
|
+ unsigned int size = sizeof(VtableBlob);
|
|
+ // align the size to CodeEntryAlignment
|
|
+ size = align_code_offset(size);
|
|
+ size += round_to(buffer_size, oopSize);
|
|
+ assert(name != NULL, "must provide a name");
|
|
+ {
|
|
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
|
+ blob = new (size) VtableBlob(name, size);
|
|
+ }
|
|
+ // Track memory usage statistic after releasing CodeCache_lock
|
|
+ MemoryService::track_code_cache_memory_usage();
|
|
+
|
|
+ return blob;
|
|
+}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Implementation of MethodHandlesAdapterBlob
|
|
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/codeBlob.hpp 2018-09-18 10:17:46.065548902 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/codeBlob.hpp 2018-09-18 10:18:04.537649500 +0200
|
|
@@ -101,6 +101,7 @@
|
|
virtual bool is_exception_stub() const { return false; }
|
|
virtual bool is_safepoint_stub() const { return false; }
|
|
virtual bool is_adapter_blob() const { return false; }
|
|
+ virtual bool is_vtable_blob() const { return false; }
|
|
virtual bool is_method_handles_adapter_blob() const { return false; }
|
|
|
|
virtual bool is_compiled_by_c2() const { return false; }
|
|
@@ -202,6 +203,7 @@
|
|
class BufferBlob: public CodeBlob {
|
|
friend class VMStructs;
|
|
friend class AdapterBlob;
|
|
+ friend class VtableBlob;
|
|
friend class MethodHandlesAdapterBlob;
|
|
|
|
private:
|
|
@@ -246,6 +248,18 @@
|
|
virtual bool is_adapter_blob() const { return true; }
|
|
};
|
|
|
|
+//---------------------------------------------------------------------------------------------------
|
|
+class VtableBlob: public BufferBlob {
|
|
+private:
|
|
+ VtableBlob(const char*, int);
|
|
+
|
|
+public:
|
|
+ // Creation
|
|
+ static VtableBlob* create(const char* name, int buffer_size);
|
|
+
|
|
+ // Typing
|
|
+ virtual bool is_vtable_blob() const { return true; }
|
|
+};
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// MethodHandlesAdapterBlob: used to hold MethodHandles adapters
|
|
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/compiledIC.cpp 2018-09-18 10:17:46.065548902 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/compiledIC.cpp 2018-09-18 10:18:04.585649761 +0200
|
|
@@ -232,7 +232,7 @@
|
|
assert(k->verify_itable_index(itable_index), "sanity check");
|
|
#endif //ASSERT
|
|
CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
|
|
- call_info->resolved_klass()());
|
|
+ call_info->resolved_klass()(), false);
|
|
holder->claim();
|
|
InlineCacheBuffer::create_transition_stub(this, holder, entry);
|
|
} else {
|
|
@@ -270,7 +270,7 @@
|
|
assert(!is_optimized(), "an optimized call cannot be megamorphic");
|
|
|
|
// Cannot rely on cached_value. It is either an interface or a method.
|
|
- return VtableStubs::is_entry_point(ic_destination());
|
|
+ return VtableStubs::entry_point(ic_destination()) != NULL;
|
|
}
|
|
|
|
bool CompiledIC::is_call_to_compiled() const {
|
|
@@ -534,9 +534,11 @@
|
|
return true;
|
|
}
|
|
// itable stubs also use CompiledICHolder
|
|
- if (VtableStubs::is_entry_point(entry) && VtableStubs::stub_containing(entry)->is_itable_stub()) {
|
|
- return true;
|
|
+ if (cb != NULL && cb->is_vtable_blob()) {
|
|
+ VtableStub* s = VtableStubs::entry_point(entry);
|
|
+ return (s != NULL) && s->is_itable_stub();
|
|
}
|
|
+
|
|
return false;
|
|
}
|
|
|
|
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/vtableStubs.cpp 2018-09-18 10:17:46.065548902 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/vtableStubs.cpp 2018-09-18 10:18:04.585649761 +0200
|
|
@@ -60,7 +60,7 @@
|
|
|
|
// There is a dependency on the name of the blob in src/share/vm/prims/jvmtiCodeBlobEvents.cpp
|
|
// If changing the name, update the other file accordingly.
|
|
- BufferBlob* blob = BufferBlob::create("vtable chunks", bytes);
|
|
+ VtableBlob* blob = VtableBlob::create("vtable chunks", bytes);
|
|
if (blob == NULL) {
|
|
return NULL;
|
|
}
|
|
@@ -167,16 +167,17 @@
|
|
_number_of_vtable_stubs++;
|
|
}
|
|
|
|
-
|
|
-bool VtableStubs::is_entry_point(address pc) {
|
|
+VtableStub* VtableStubs::entry_point(address pc) {
|
|
MutexLocker ml(VtableStubs_lock);
|
|
VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset());
|
|
uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index());
|
|
VtableStub* s;
|
|
for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {}
|
|
- return s == stub;
|
|
+ if (s == stub) {
|
|
+ return s;
|
|
+ }
|
|
+ return NULL;
|
|
}
|
|
-
|
|
|
|
bool VtableStubs::contains(address pc) {
|
|
// simple solution for now - we may want to use
|
|
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/vtableStubs.hpp 2018-09-18 10:17:46.065548902 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/code/vtableStubs.hpp 2018-09-18 10:18:04.585649761 +0200
|
|
@@ -126,7 +126,7 @@
|
|
public:
|
|
static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); }
|
|
static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); }
|
|
- static bool is_entry_point(address pc); // is pc a vtable stub entry point?
|
|
+ static VtableStub* entry_point(address pc); // vtable stub entry point for a pc
|
|
static bool contains(address pc); // is pc within any stub?
|
|
static VtableStub* stub_containing(address pc); // stub containing pc or NULL
|
|
static int number_of_vtable_stubs() { return _number_of_vtable_stubs; }
|
|
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/oops/compiledICHolder.cpp 2018-09-18 10:17:46.073548946 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/oops/compiledICHolder.cpp 2018-09-18 10:18:04.585649761 +0200
|
|
@@ -24,30 +24,12 @@
|
|
|
|
#include "precompiled.hpp"
|
|
#include "oops/compiledICHolder.hpp"
|
|
-#include "oops/klass.hpp"
|
|
-#include "oops/method.hpp"
|
|
#include "oops/oop.inline2.hpp"
|
|
|
|
volatile int CompiledICHolder::_live_count;
|
|
volatile int CompiledICHolder::_live_not_claimed_count;
|
|
|
|
|
|
-bool CompiledICHolder::is_loader_alive(BoolObjectClosure* is_alive) {
|
|
- if (_holder_metadata->is_method()) {
|
|
- if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) {
|
|
- return false;
|
|
- }
|
|
- } else if (_holder_metadata->is_klass()) {
|
|
- if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) {
|
|
- return false;
|
|
- }
|
|
- }
|
|
- if (!_holder_klass->is_loader_alive(is_alive)) {
|
|
- return false;
|
|
- }
|
|
- return true;
|
|
-}
|
|
-
|
|
// Printing
|
|
|
|
void CompiledICHolder::print_on(outputStream* st) const {
|
|
--- icedtea-3.8.0/openjdk/hotspot/src/share/vm/oops/compiledICHolder.hpp 2018-09-18 10:17:46.073548946 +0200
|
|
+++ icedtea-3.8.0/openjdk/hotspot/src/share/vm/oops/compiledICHolder.hpp 2018-09-18 10:18:04.585649761 +0200
|
|
@@ -26,6 +26,8 @@
|
|
#define SHARE_VM_OOPS_COMPILEDICHOLDEROOP_HPP
|
|
|
|
#include "oops/oop.hpp"
|
|
+#include "oops/klass.hpp"
|
|
+#include "oops/method.hpp"
|
|
|
|
// A CompiledICHolder* is a helper object for the inline cache implementation.
|
|
// It holds:
|
|
@@ -48,11 +50,12 @@
|
|
Metadata* _holder_metadata;
|
|
Klass* _holder_klass; // to avoid name conflict with oopDesc::_klass
|
|
CompiledICHolder* _next;
|
|
+ bool _is_metadata_method;
|
|
|
|
public:
|
|
// Constructor
|
|
- CompiledICHolder(Metadata* metadata, Klass* klass)
|
|
- : _holder_metadata(metadata), _holder_klass(klass) {
|
|
+ CompiledICHolder(Metadata* metadata, Klass* klass, bool is_method = true)
|
|
+ : _holder_metadata(metadata), _holder_klass(klass), _is_metadata_method(is_method) {
|
|
#ifdef ASSERT
|
|
Atomic::inc(&_live_count);
|
|
Atomic::inc(&_live_not_claimed_count);
|
|
@@ -82,7 +85,16 @@
|
|
CompiledICHolder* next() { return _next; }
|
|
void set_next(CompiledICHolder* n) { _next = n; }
|
|
|
|
- bool is_loader_alive(BoolObjectClosure* is_alive);
|
|
+ inline bool is_loader_alive(BoolObjectClosure* is_alive) {
|
|
+ Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata;
|
|
+ if (!k->is_loader_alive(is_alive)) {
|
|
+ return false;
|
|
+ }
|
|
+ if (!_holder_klass->is_loader_alive(is_alive)) {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
|
|
// Verify
|
|
void verify_on(outputStream* st);
|