mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8059624: Test task: WhiteBox API for testing segmented codecache feature
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
80830d4932
commit
bdac822811
18 changed files with 687 additions and 35 deletions
|
@ -43,7 +43,7 @@
|
|||
#include "c1/c1_Runtime1.hpp"
|
||||
#endif
|
||||
|
||||
unsigned int align_code_offset(int offset) {
|
||||
unsigned int CodeBlob::align_code_offset(int offset) {
|
||||
// align the size to CodeEntryAlignment
|
||||
return
|
||||
((offset + (int)CodeHeap::header_size() + (CodeEntryAlignment-1)) & ~(CodeEntryAlignment-1))
|
||||
|
|
|
@ -83,6 +83,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||
public:
|
||||
// Returns the space needed for CodeBlob
|
||||
static unsigned int allocation_size(CodeBuffer* cb, int header_size);
|
||||
static unsigned int align_code_offset(int offset);
|
||||
|
||||
// Creation
|
||||
// a) simple CodeBlob
|
||||
|
@ -207,7 +208,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
class WhiteBox;
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
|
||||
|
||||
|
@ -215,6 +216,7 @@ class BufferBlob: public CodeBlob {
|
|||
friend class VMStructs;
|
||||
friend class AdapterBlob;
|
||||
friend class MethodHandlesAdapterBlob;
|
||||
friend class WhiteBox;
|
||||
|
||||
private:
|
||||
// Creation support
|
||||
|
|
|
@ -305,7 +305,7 @@ void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial
|
|||
MemoryService::add_code_heap_memory_pool(heap, name);
|
||||
}
|
||||
|
||||
CodeHeap* CodeCache::get_code_heap(CodeBlob* cb) {
|
||||
CodeHeap* CodeCache::get_code_heap(const CodeBlob* cb) {
|
||||
assert(cb != NULL, "CodeBlob is null");
|
||||
FOR_ALL_HEAPS(heap) {
|
||||
if ((*heap)->contains(cb)) {
|
||||
|
|
|
@ -77,6 +77,7 @@ class DepChange;
|
|||
class CodeCache : AllStatic {
|
||||
friend class VMStructs;
|
||||
friend class NMethodIterator;
|
||||
friend class WhiteBox;
|
||||
private:
|
||||
// CodeHeaps of the cache
|
||||
static GrowableArray<CodeHeap*>* _heaps;
|
||||
|
@ -98,7 +99,7 @@ class CodeCache : AllStatic {
|
|||
static void initialize_heaps(); // Initializes the CodeHeaps
|
||||
// Creates a new heap with the given name and size, containing CodeBlobs of the given type
|
||||
static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type);
|
||||
static CodeHeap* get_code_heap(CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob
|
||||
static CodeHeap* get_code_heap(const CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob
|
||||
static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType
|
||||
// Returns the name of the VM option to set the size of the corresponding CodeHeap
|
||||
static const char* get_code_heap_flag_name(int code_blob_type);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "oops/method.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/nativeLookup.hpp"
|
||||
#include "prims/whitebox.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/atomic.inline.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
|
@ -1963,6 +1964,12 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
|||
if (comp == NULL) {
|
||||
ci_env.record_method_not_compilable("no compiler", !TieredCompilation);
|
||||
} else {
|
||||
if (WhiteBoxAPI && WhiteBox::compilation_locked) {
|
||||
MonitorLockerEx locker(Compilation_lock, Mutex::_no_safepoint_check_flag);
|
||||
while (WhiteBox::compilation_locked) {
|
||||
locker.wait(Mutex::_no_safepoint_check_flag);
|
||||
}
|
||||
}
|
||||
comp->compile_method(&ci_env, target, osr_bci);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "code/codeCache.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
|
@ -37,9 +39,11 @@
|
|||
|
||||
#include "runtime/thread.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "runtime/sweeper.hpp"
|
||||
|
||||
#include "utilities/array.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
@ -67,6 +71,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
|||
#define SIZE_T_MAX_VALUE ((size_t) -1)
|
||||
|
||||
bool WhiteBox::_used = false;
|
||||
volatile bool WhiteBox::compilation_locked = false;
|
||||
|
||||
WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
|
||||
return (jlong)(void*)JNIHandles::resolve(obj);
|
||||
|
@ -308,7 +313,6 @@ WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
|
|||
return addr;
|
||||
WB_END
|
||||
|
||||
|
||||
WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
|
||||
os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
|
||||
MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
|
||||
|
@ -728,6 +732,29 @@ WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring
|
|||
WB_END
|
||||
|
||||
|
||||
WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
|
||||
WhiteBox::compilation_locked = true;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
|
||||
MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
|
||||
WhiteBox::compilation_locked = false;
|
||||
mo.notify_all();
|
||||
WB_END
|
||||
|
||||
void WhiteBox::force_sweep() {
|
||||
guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
|
||||
{
|
||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
NMethodSweeper::_should_sweep = true;
|
||||
}
|
||||
NMethodSweeper::possibly_sweep();
|
||||
}
|
||||
|
||||
WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
|
||||
WhiteBox::force_sweep();
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
|
||||
ResourceMark rm(THREAD);
|
||||
int len;
|
||||
|
@ -774,6 +801,46 @@ WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o))
|
|||
return features_string;
|
||||
WB_END
|
||||
|
||||
int WhiteBox::get_blob_type(const CodeBlob* code) {
|
||||
guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
|
||||
return CodeCache::get_code_heap(code)->code_blob_type();
|
||||
}
|
||||
|
||||
CodeHeap* WhiteBox::get_code_heap(int blob_type) {
|
||||
guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
|
||||
return CodeCache::get_code_heap(blob_type);
|
||||
}
|
||||
|
||||
struct CodeBlobStub {
|
||||
CodeBlobStub(const CodeBlob* blob) :
|
||||
name(os::strdup(blob->name())),
|
||||
size(blob->size()),
|
||||
blob_type(WhiteBox::get_blob_type(blob)) { }
|
||||
~CodeBlobStub() { os::free((void*) name); }
|
||||
const char* const name;
|
||||
const int size;
|
||||
const int blob_type;
|
||||
};
|
||||
|
||||
static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
|
||||
jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
jobjectArray result = env->NewObjectArray(3, clazz, NULL);
|
||||
|
||||
jstring name = env->NewStringUTF(cb->name);
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
env->SetObjectArrayElement(result, 0, name);
|
||||
|
||||
jobject obj = integerBox(thread, env, cb->size);
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
env->SetObjectArrayElement(result, 1, obj);
|
||||
|
||||
obj = integerBox(thread, env, cb->blob_type);
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
env->SetObjectArrayElement(result, 2, obj);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
|
||||
ResourceMark rm(THREAD);
|
||||
|
@ -790,27 +857,93 @@ WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jbo
|
|||
ThreadToNativeFromVM ttn(thread);
|
||||
jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
result = env->NewObjectArray(3, clazz, NULL);
|
||||
result = env->NewObjectArray(4, clazz, NULL);
|
||||
if (result == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBlobStub stub(code);
|
||||
jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub);
|
||||
env->SetObjectArrayElement(result, 0, codeBlob);
|
||||
|
||||
jobject level = integerBox(thread, env, code->comp_level());
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
env->SetObjectArrayElement(result, 0, level);
|
||||
env->SetObjectArrayElement(result, 1, level);
|
||||
|
||||
jbyteArray insts = env->NewByteArray(insts_size);
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
|
||||
env->SetObjectArrayElement(result, 1, insts);
|
||||
env->SetObjectArrayElement(result, 2, insts);
|
||||
|
||||
jobject id = integerBox(thread, env, code->compile_id());
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
env->SetObjectArrayElement(result, 2, id);
|
||||
env->SetObjectArrayElement(result, 3, id);
|
||||
|
||||
return result;
|
||||
WB_END
|
||||
|
||||
CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
|
||||
guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
|
||||
BufferBlob* blob;
|
||||
int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
|
||||
if (full_size < size) {
|
||||
full_size += round_to(size - full_size, oopSize);
|
||||
}
|
||||
{
|
||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
|
||||
}
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
::new (blob) BufferBlob("WB::DummyBlob", full_size);
|
||||
return blob;
|
||||
}
|
||||
|
||||
WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
|
||||
return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
|
||||
BufferBlob::free((BufferBlob*) addr);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
|
||||
ResourceMark rm;
|
||||
GrowableArray<CodeBlobStub*> blobs;
|
||||
{
|
||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
CodeHeap* heap = WhiteBox::get_code_heap(blob_type);
|
||||
if (heap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (CodeBlob* cb = (CodeBlob*) heap->first();
|
||||
cb != NULL; cb = (CodeBlob*) heap->next(cb)) {
|
||||
CodeBlobStub* stub = NEW_RESOURCE_OBJ(CodeBlobStub);
|
||||
new (stub) CodeBlobStub(cb);
|
||||
blobs.append(stub);
|
||||
}
|
||||
}
|
||||
if (blobs.length() == 0) {
|
||||
return NULL;
|
||||
}
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
jobjectArray result = NULL;
|
||||
jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
|
||||
CHECK_JNI_EXCEPTION_(env, NULL);
|
||||
result = env->NewObjectArray(blobs.length(), clazz, NULL);
|
||||
if (result == NULL) {
|
||||
return result;
|
||||
}
|
||||
int i = 0;
|
||||
for (GrowableArrayIterator<CodeBlobStub*> it = blobs.begin();
|
||||
it != blobs.end(); ++it) {
|
||||
jobjectArray obj = codeBlob2objectArray(thread, env, *it);
|
||||
env->SetObjectArrayElement(result, i, obj);
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o))
|
||||
return (jlong) Thread::current()->stack_size();
|
||||
WB_END
|
||||
|
@ -1018,6 +1151,8 @@ static JNINativeMethod methods[] = {
|
|||
CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation},
|
||||
{CC"clearMethodState",
|
||||
CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
|
||||
{CC"lockCompilation", CC"()V", (void*)&WB_LockCompilation},
|
||||
{CC"unlockCompilation", CC"()V", (void*)&WB_UnlockCompilation},
|
||||
{CC"isConstantVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
|
||||
{CC"isLockedVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
|
||||
{CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
|
||||
|
@ -1055,6 +1190,10 @@ static JNINativeMethod methods[] = {
|
|||
{CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures },
|
||||
{CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
|
||||
(void*)&WB_GetNMethod },
|
||||
{CC"forceNMethodSweep", CC"()V", (void*)&WB_ForceNMethodSweep },
|
||||
{CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob },
|
||||
{CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob },
|
||||
{CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
|
||||
{CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize },
|
||||
{CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize },
|
||||
};
|
||||
|
|
|
@ -54,17 +54,24 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
class CodeBlob;
|
||||
class CodeHeap;
|
||||
|
||||
class WhiteBox : public AllStatic {
|
||||
private:
|
||||
static bool _used;
|
||||
public:
|
||||
static volatile bool compilation_locked;
|
||||
static bool used() { return _used; }
|
||||
static void set_used() { _used = true; }
|
||||
static int offset_for_field(const char* field_name, oop object,
|
||||
Symbol* signature_symbol);
|
||||
static const char* lookup_jstring(const char* field_name, oop object);
|
||||
static bool lookup_bool(const char* field_name, oop object);
|
||||
|
||||
static void force_sweep();
|
||||
static int get_blob_type(const CodeBlob* code);
|
||||
static CodeHeap* get_code_heap(int blob_type);
|
||||
static CodeBlob* allocate_code_blob(int blob_type, int size);
|
||||
static int array_bytes_to_length(size_t bytes);
|
||||
static void register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread,
|
||||
JNINativeMethod* method_array, int method_count);
|
||||
|
|
|
@ -88,6 +88,7 @@ Mutex* DerivedPointerTableGC_lock = NULL;
|
|||
Mutex* Compile_lock = NULL;
|
||||
Monitor* MethodCompileQueue_lock = NULL;
|
||||
Monitor* CompileThread_lock = NULL;
|
||||
Monitor* Compilation_lock = NULL;
|
||||
Mutex* CompileTaskAlloc_lock = NULL;
|
||||
Mutex* CompileStatistics_lock = NULL;
|
||||
Mutex* MultiArray_lock = NULL;
|
||||
|
@ -278,7 +279,9 @@ void mutex_init() {
|
|||
def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread
|
||||
def(CompileThread_lock , Monitor, nonleaf+5, false );
|
||||
def(PeriodicTask_lock , Monitor, nonleaf+5, true);
|
||||
|
||||
if (WhiteBoxAPI) {
|
||||
def(Compilation_lock , Monitor, leaf, false );
|
||||
}
|
||||
#ifdef INCLUDE_TRACE
|
||||
def(JfrMsg_lock , Monitor, leaf, true);
|
||||
def(JfrBuffer_lock , Mutex, leaf, true);
|
||||
|
|
|
@ -91,6 +91,7 @@ extern Mutex* EvacFailureStack_lock; // guards the evac failure scan
|
|||
extern Mutex* Compile_lock; // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
|
||||
extern Monitor* MethodCompileQueue_lock; // a lock held when method compilations are enqueued, dequeued
|
||||
extern Monitor* CompileThread_lock; // a lock held by compile threads during compilation system initialization
|
||||
extern Monitor* Compilation_lock; // a lock used to pause compilation
|
||||
extern Mutex* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated
|
||||
extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics
|
||||
extern Mutex* MultiArray_lock; // a lock used to guard allocation of multi-dim arrays
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef SHARE_VM_RUNTIME_SWEEPER_HPP
|
||||
#define SHARE_VM_RUNTIME_SWEEPER_HPP
|
||||
|
||||
class WhiteBox;
|
||||
|
||||
#include "utilities/ticks.hpp"
|
||||
// An NmethodSweeper is an incremental cleaner for:
|
||||
// - cleanup inline caches
|
||||
|
@ -52,6 +54,8 @@
|
|||
// nmethod's space is freed.
|
||||
|
||||
class NMethodSweeper : public AllStatic {
|
||||
friend class WhiteBox;
|
||||
private:
|
||||
static long _traversals; // Stack scan count, also sweep ID.
|
||||
static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache
|
||||
static long _time_counter; // Virtual time used to periodically invoke sweeper
|
||||
|
@ -88,7 +92,6 @@ class NMethodSweeper : public AllStatic {
|
|||
static void handle_safepoint_request();
|
||||
static void do_stack_scanning();
|
||||
static void possibly_sweep();
|
||||
|
||||
public:
|
||||
static long traversal_count() { return _traversals; }
|
||||
static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; }
|
||||
|
|
128
hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java
Normal file
128
hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.util.EnumSet;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import sun.hotspot.WhiteBox;
|
||||
import sun.hotspot.code.BlobType;
|
||||
import com.oracle.java.testlibrary.Asserts;
|
||||
|
||||
/*
|
||||
* @test AllocationCodeBlobTest
|
||||
* @bug 8059624
|
||||
* @library /testlibrary /testlibrary/whitebox
|
||||
* @build AllocationCodeBlobTest
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::*
|
||||
* -XX:-SegmentedCodeCache AllocationCodeBlobTest
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::*
|
||||
* -XX:+SegmentedCodeCache AllocationCodeBlobTest
|
||||
* @summary testing of WB::allocate/freeCodeBlob()
|
||||
*/
|
||||
public class AllocationCodeBlobTest {
|
||||
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
|
||||
private static final long CODE_CACHE_SIZE
|
||||
= WHITE_BOX.getUintxVMFlag("ReservedCodeCacheSize");
|
||||
private static final int SIZE = 1;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// check that Sweeper handels dummy blobs correctly
|
||||
new ForcedSweeper(500).start();
|
||||
EnumSet<BlobType> blobTypes = BlobType.getAvailable();
|
||||
for (BlobType type : blobTypes) {
|
||||
new AllocationCodeBlobTest(type).test();
|
||||
}
|
||||
}
|
||||
|
||||
private final BlobType type;
|
||||
private final MemoryPoolMXBean bean;
|
||||
private AllocationCodeBlobTest(BlobType type) {
|
||||
this.type = type;
|
||||
bean = type.getMemoryPool();
|
||||
}
|
||||
|
||||
private void test() {
|
||||
System.out.printf("type %s%n", type);
|
||||
long start = getUsage();
|
||||
long addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
|
||||
Asserts.assertNE(0, addr, "allocation failed");
|
||||
|
||||
long firstAllocation = getUsage();
|
||||
Asserts.assertLTE(start + SIZE, firstAllocation,
|
||||
"allocation should increase memory usage: "
|
||||
+ start + " + " + SIZE + " <= " + firstAllocation);
|
||||
|
||||
WHITE_BOX.freeCodeBlob(addr);
|
||||
long firstFree = getUsage();
|
||||
Asserts.assertLTE(firstFree, firstAllocation,
|
||||
"free shouldn't increase memory usage: "
|
||||
+ firstFree + " <= " + firstAllocation);
|
||||
|
||||
addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
|
||||
Asserts.assertNE(0, addr, "allocation failed");
|
||||
|
||||
long secondAllocation = getUsage();
|
||||
Asserts.assertEQ(firstAllocation, secondAllocation);
|
||||
|
||||
WHITE_BOX.freeCodeBlob(addr);
|
||||
System.out.println("allocating till possible...");
|
||||
ArrayList<Long> blobs = new ArrayList<>();
|
||||
int size = (int) (CODE_CACHE_SIZE >> 7);
|
||||
while ((addr = WHITE_BOX.allocateCodeBlob(size, type.id)) != 0) {
|
||||
blobs.add(addr);
|
||||
}
|
||||
for (Long blob : blobs) {
|
||||
WHITE_BOX.freeCodeBlob(blob);
|
||||
}
|
||||
}
|
||||
|
||||
private long getUsage() {
|
||||
return bean.getUsage().getUsed();
|
||||
}
|
||||
|
||||
private static class ForcedSweeper extends Thread {
|
||||
private final int millis;
|
||||
public ForcedSweeper(int millis) {
|
||||
super("ForcedSweeper");
|
||||
setDaemon(true);
|
||||
this.millis = millis;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
WHITE_BOX.forceNMethodSweep();
|
||||
Thread.sleep(millis);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java
Normal file
95
hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import sun.hotspot.WhiteBox;
|
||||
import sun.hotspot.code.CodeBlob;
|
||||
import sun.hotspot.code.BlobType;
|
||||
import com.oracle.java.testlibrary.Asserts;
|
||||
|
||||
/*
|
||||
* @test GetCodeHeapEntriesTest
|
||||
* @bug 8059624
|
||||
* @library /testlibrary /testlibrary/whitebox
|
||||
* @build GetCodeHeapEntriesTest
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache
|
||||
* GetCodeHeapEntriesTest
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache
|
||||
* GetCodeHeapEntriesTest
|
||||
* @summary testing of WB::getCodeHeapEntries()
|
||||
*/
|
||||
public class GetCodeHeapEntriesTest {
|
||||
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
|
||||
private static final int SIZE = 1024;
|
||||
private static final String DUMMY_NAME = "WB::DummyBlob";
|
||||
private static EnumSet<BlobType> SEGMENTED_TYPES
|
||||
= EnumSet.complementOf(EnumSet.of(BlobType.All));
|
||||
|
||||
public static void main(String[] args) {
|
||||
EnumSet<BlobType> blobTypes = BlobType.getAvailable();
|
||||
for (BlobType type : blobTypes) {
|
||||
new GetCodeHeapEntriesTest(type).test();
|
||||
}
|
||||
}
|
||||
|
||||
private final BlobType type;
|
||||
private GetCodeHeapEntriesTest(BlobType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private void test() {
|
||||
System.out.printf("type %s%n", type);
|
||||
long addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
|
||||
Asserts.assertNE(0, addr, "allocation failed");
|
||||
CodeBlob[] blobs = CodeBlob.getCodeBlobs(type);
|
||||
Asserts.assertNotNull(blobs);
|
||||
CodeBlob blob = Arrays.stream(blobs)
|
||||
.filter(GetCodeHeapEntriesTest::filter)
|
||||
.findAny()
|
||||
.get();
|
||||
Asserts.assertNotNull(blob);
|
||||
Asserts.assertEQ(blob.code_blob_type, type);
|
||||
Asserts.assertGTE(blob.size, SIZE);
|
||||
|
||||
WHITE_BOX.freeCodeBlob(addr);
|
||||
blobs = CodeBlob.getCodeBlobs(type);
|
||||
long count = Arrays.stream(blobs)
|
||||
.filter(GetCodeHeapEntriesTest::filter)
|
||||
.count();
|
||||
Asserts.assertEQ(0L, count);
|
||||
}
|
||||
|
||||
private static boolean filter(CodeBlob blob) {
|
||||
if (blob == null) {
|
||||
return false;
|
||||
}
|
||||
return DUMMY_NAME.equals(blob.name);
|
||||
}
|
||||
}
|
|
@ -22,7 +22,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import sun.hotspot.code.BlobType;
|
||||
import sun.hotspot.code.NMethod;
|
||||
import com.oracle.java.testlibrary.Asserts;
|
||||
|
||||
/*
|
||||
* @test GetNMethodTest
|
||||
|
@ -52,21 +54,46 @@ public class GetNMethodTest extends CompilerWhiteBoxTest {
|
|||
|
||||
compile();
|
||||
checkCompiled();
|
||||
|
||||
NMethod nmethod = NMethod.get(method, testCase.isOsr());
|
||||
if (IS_VERBOSE) {
|
||||
System.out.println("nmethod = " + nmethod);
|
||||
}
|
||||
if (nmethod == null) {
|
||||
throw new RuntimeException("nmethod of compiled method is null");
|
||||
Asserts.assertNotNull(nmethod,
|
||||
"nmethod of compiled method is null");
|
||||
Asserts.assertNotNull(nmethod.insts,
|
||||
"nmethod.insts of compiled method is null");
|
||||
Asserts.assertGT(nmethod.insts.length, 0,
|
||||
"compiled method's instructions is empty");
|
||||
Asserts.assertNotNull(nmethod.code_blob_type, "blob type is null");
|
||||
if (WHITE_BOX.getBooleanVMFlag("SegmentedCodeCache")) {
|
||||
Asserts.assertNE(nmethod.code_blob_type, BlobType.All);
|
||||
switch (nmethod.comp_level) {
|
||||
case 1:
|
||||
case 4:
|
||||
checkBlockType(nmethod, BlobType.MethodNonProfiled);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
checkBlockType(nmethod, BlobType.MethodNonProfiled);
|
||||
break;
|
||||
default:
|
||||
throw new Error("unexpected comp level " + nmethod);
|
||||
}
|
||||
if (nmethod.insts.length == 0) {
|
||||
throw new RuntimeException("compiled method's instructions is empty");
|
||||
} else {
|
||||
Asserts.assertEQ(nmethod.code_blob_type, BlobType.All);
|
||||
}
|
||||
|
||||
deoptimize();
|
||||
checkNotCompiled();
|
||||
nmethod = NMethod.get(method, testCase.isOsr());
|
||||
if (nmethod != null) {
|
||||
throw new RuntimeException("nmethod of non-compiled method isn't null");
|
||||
Asserts.assertNull(nmethod,
|
||||
"nmethod of non-compiled method isn't null");
|
||||
}
|
||||
|
||||
private void checkBlockType(NMethod nmethod, BlobType expectedType) {
|
||||
Asserts.assertEQ(nmethod.code_blob_type, expectedType,
|
||||
String.format("blob_type[%s] for %d level isn't %s",
|
||||
nmethod.code_blob_type, nmethod.comp_level, expectedType));
|
||||
}
|
||||
}
|
||||
|
|
91
hotspot/test/compiler/whitebox/LockCompilationTest.java
Normal file
91
hotspot/test/compiler/whitebox/LockCompilationTest.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test LockCompilationTest
|
||||
* @bug 8059624
|
||||
* @library /testlibrary /testlibrary/whitebox
|
||||
* @build LockCompilationTest
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* LockCompilationTest
|
||||
* @summary testing of WB::lock/unlockCompilation()
|
||||
*/
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
|
||||
import com.oracle.java.testlibrary.Asserts;
|
||||
|
||||
public class LockCompilationTest extends CompilerWhiteBoxTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
CompilerWhiteBoxTest.main(LockCompilationTest::new, args);
|
||||
}
|
||||
|
||||
private LockCompilationTest(TestCase testCase) {
|
||||
super(testCase);
|
||||
// to prevent inlining of #method
|
||||
WHITE_BOX.testSetDontInlineMethod(method, true);
|
||||
}
|
||||
|
||||
protected void test() throws Exception {
|
||||
checkNotCompiled();
|
||||
|
||||
System.out.println("locking compilation");
|
||||
WHITE_BOX.lockCompilation();
|
||||
|
||||
try {
|
||||
System.out.println("trying to compile");
|
||||
compile();
|
||||
// to check if it works correctly w/ safepoints
|
||||
System.out.println("going to safepoint");
|
||||
WHITE_BOX.fullGC();
|
||||
waitBackgroundCompilation();
|
||||
Asserts.assertTrue(
|
||||
WHITE_BOX.isMethodQueuedForCompilation(method),
|
||||
method + " must be in queue");
|
||||
Asserts.assertFalse(
|
||||
WHITE_BOX.isMethodCompiled(method, false),
|
||||
method + " must be not compiled");
|
||||
Asserts.assertEQ(
|
||||
WHITE_BOX.getMethodCompilationLevel(method, false), 0,
|
||||
method + " comp_level must be == 0");
|
||||
Asserts.assertFalse(
|
||||
WHITE_BOX.isMethodCompiled(method, true),
|
||||
method + " must be not osr_compiled");
|
||||
Asserts.assertEQ(
|
||||
WHITE_BOX.getMethodCompilationLevel(method, true), 0,
|
||||
method + " osr_comp_level must be == 0");
|
||||
} finally {
|
||||
System.out.println("unlocking compilation");
|
||||
WHITE_BOX.unlockCompilation();
|
||||
}
|
||||
waitBackgroundCompilation();
|
||||
Asserts.assertFalse(
|
||||
WHITE_BOX.isMethodQueuedForCompilation(method),
|
||||
method + " must not be in queue");
|
||||
}
|
||||
}
|
||||
|
|
@ -143,8 +143,14 @@ public class WhiteBox {
|
|||
}
|
||||
public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci);
|
||||
public native void clearMethodState(Executable method);
|
||||
public native void lockCompilation();
|
||||
public native void unlockCompilation();
|
||||
public native int getMethodEntryBci(Executable method);
|
||||
public native Object[] getNMethod(Executable method, boolean isOsr);
|
||||
public native long allocateCodeBlob(int size, int type);
|
||||
public native void freeCodeBlob(long addr);
|
||||
public native void forceNMethodSweep();
|
||||
public native Object[] getCodeHeapEntries(int type);
|
||||
|
||||
// Intered strings
|
||||
public native boolean isInStringTable(String str);
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.hotspot.code;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
public enum BlobType {
|
||||
// Execution level 1 and 4 (non-profiled) nmethods (including native nmethods)
|
||||
MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"),
|
||||
// Execution level 2 and 3 (profiled) nmethods
|
||||
MethodProfiled(1, "CodeHeap 'profiled nmethods'"),
|
||||
// Non-nmethods like Buffers, Adapters and Runtime Stubs
|
||||
NonNMethod(2, "CodeHeap 'non-nmethods'"),
|
||||
// All types (No code cache segmentation)
|
||||
All(3, "CodeCache");
|
||||
|
||||
public final int id;
|
||||
private final String beanName;
|
||||
|
||||
private BlobType(int id, String beanName) {
|
||||
this.id = id;
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
public MemoryPoolMXBean getMemoryPool() {
|
||||
for (MemoryPoolMXBean bean : ManagementFactory.getMemoryPoolMXBeans()) {
|
||||
String name = bean.getName();
|
||||
if (beanName.equals(name)) {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static EnumSet<BlobType> getAvailable() {
|
||||
WhiteBox whiteBox = WhiteBox.getWhiteBox();
|
||||
if (!whiteBox.getBooleanVMFlag("SegmentedCodeCache")) {
|
||||
// only All for non segmented world
|
||||
return EnumSet.of(All);
|
||||
}
|
||||
if (System.getProperty("java.vm.info").startsWith("interpreted ")) {
|
||||
// only NonNMethod for -Xint
|
||||
return EnumSet.of(NonNMethod);
|
||||
}
|
||||
|
||||
EnumSet<BlobType> result = EnumSet.complementOf(EnumSet.of(All));
|
||||
if (!whiteBox.getBooleanVMFlag("TieredCompilation")
|
||||
|| whiteBox.getIntxVMFlag("TieredStopAtLevel") <= 1) {
|
||||
// there is no MethodProfiled in non tiered world or pure C1
|
||||
result.remove(MethodProfiled);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.hotspot.code;
|
||||
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
public class CodeBlob {
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
public static CodeBlob[] getCodeBlobs(BlobType type) {
|
||||
Object[] obj = WB.getCodeHeapEntries(type.id);
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
CodeBlob[] result = new CodeBlob[obj.length];
|
||||
for (int i = 0, n = result.length; i < n; ++i) {
|
||||
result[i] = new CodeBlob((Object[]) obj[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
protected CodeBlob(Object[] obj) {
|
||||
assert obj.length == 3;
|
||||
name = (String) obj[0];
|
||||
size = (Integer) obj[1];
|
||||
code_blob_type = BlobType.values()[(Integer) obj[2]];
|
||||
assert code_blob_type.id == (Integer) obj[2];
|
||||
}
|
||||
public final String name;
|
||||
public final int size;
|
||||
public final BlobType code_blob_type;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CodeBlob{"
|
||||
+ "name=" + name
|
||||
+ ", size=" + size
|
||||
+ ", code_blob_type=" + code_blob_type
|
||||
+ '}';
|
||||
}
|
||||
}
|
|
@ -27,28 +27,30 @@ package sun.hotspot.code;
|
|||
import java.lang.reflect.Executable;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
public class NMethod {
|
||||
public class NMethod extends CodeBlob {
|
||||
private static final WhiteBox wb = WhiteBox.getWhiteBox();
|
||||
public static NMethod get(Executable method, boolean isOsr) {
|
||||
Object[] obj = wb.getNMethod(method, isOsr);
|
||||
return obj == null ? null : new NMethod(obj);
|
||||
}
|
||||
private NMethod(Object[] obj) {
|
||||
assert obj.length == 3;
|
||||
comp_level = (Integer) obj[0];
|
||||
insts = (byte[]) obj[1];
|
||||
compile_id = (Integer) obj[2];
|
||||
super((Object[])obj[0]);
|
||||
assert obj.length == 4;
|
||||
comp_level = (Integer) obj[1];
|
||||
insts = (byte[]) obj[2];
|
||||
compile_id = (Integer) obj[3];
|
||||
}
|
||||
public byte[] insts;
|
||||
public int comp_level;
|
||||
public int compile_id;
|
||||
public final byte[] insts;
|
||||
public final int comp_level;
|
||||
public final int compile_id;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NMethod{" +
|
||||
"insts=" + insts +
|
||||
", comp_level=" + comp_level +
|
||||
", compile_id=" + compile_id +
|
||||
'}';
|
||||
return "NMethod{"
|
||||
+ super.toString()
|
||||
+ ", insts=" + insts
|
||||
+ ", comp_level=" + comp_level
|
||||
+ ", compile_id=" + compile_id
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue