Merge
This commit is contained in:
commit
a079697817
@ -131,3 +131,4 @@ b910aac18c772b823b1f7da03e2c6528725cc6de jdk8-b05
|
||||
0db7ae9f2b1017124c779bccd016c976928859a0 jdk8-b07
|
||||
fb1bc13260d76447e269e843859eb593fe2a8ab2 jdk8-b08
|
||||
8adb70647b5af5273dfe6a540f07be667cd50216 jdk8-b09
|
||||
a6c4c248e8fa350c35014fa94bab5ac1a1ac3299 jdk8-b10
|
||||
|
@ -131,3 +131,4 @@ cc1b599b986a37cb57de4584c5e58169766ca535 jdk8-b05
|
||||
3d61f0856f349e2163bf98146465dab3b7437f63 jdk8-b07
|
||||
0d52b1c87aa8fdea7fdc9c4126ea58f95ca6b351 jdk8-b08
|
||||
a891732c1a83082177ff7a4cf1506068d9cc0a47 jdk8-b09
|
||||
cda87f7fefcee3b89742a57ce5ad9b03a54c210d jdk8-b10
|
||||
|
@ -6,3 +6,4 @@
|
||||
^src/share/tools/IdealGraphVisualizer/build/
|
||||
^src/share/tools/IdealGraphVisualizer/dist/
|
||||
^.hgtip
|
||||
.DS_Store
|
||||
|
@ -191,3 +191,5 @@ da883b9e6d3788057f9577e72712998ed82c9b7e hs23-b01
|
||||
49ed7eacfd16616166ff066493143889741097af jdk8-b08
|
||||
7c20d272643f47195478708eff593a9cce40fec4 jdk8-b09
|
||||
e4f412d2b75d2c797acff965aa2c420e3d358f09 hs23-b02
|
||||
d815de2e85e511b7deab2a83cf80c0224d011da9 jdk8-b10
|
||||
4d3850d9d326ac3a9bee2d867727e954322d014e hs23-b03
|
||||
|
406
hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
Normal file
406
hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
Normal file
@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, 2011, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <objc/objc-runtime.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
#include <JavaVM/jni.h>
|
||||
|
||||
#import <mach/mach.h>
|
||||
#import <mach/mach_types.h>
|
||||
#import <sys/sysctl.h>
|
||||
#import <stdlib.h>
|
||||
|
||||
jboolean debug = JNI_FALSE;
|
||||
|
||||
static jfieldID symbolicatorID = 0; // set in _init0
|
||||
static jfieldID taskID = 0; // set in _init0
|
||||
|
||||
static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) {
|
||||
(*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator);
|
||||
}
|
||||
|
||||
static id getSymbolicator(JNIEnv *env, jobject this_obj) {
|
||||
jlong ptr = (*env)->GetLongField(env, this_obj, symbolicatorID);
|
||||
return (id)(intptr_t)ptr;
|
||||
}
|
||||
|
||||
static void putTask(JNIEnv *env, jobject this_obj, task_t task) {
|
||||
(*env)->SetLongField(env, this_obj, taskID, (jlong)task);
|
||||
}
|
||||
|
||||
static task_t getTask(JNIEnv *env, jobject this_obj) {
|
||||
jlong ptr = (*env)->GetLongField(env, this_obj, taskID);
|
||||
return (task_t)ptr;
|
||||
}
|
||||
|
||||
#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
|
||||
#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
|
||||
#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
|
||||
#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
|
||||
|
||||
static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
|
||||
(*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
#define hsdb_thread_state_t x86_thread_state32_t
|
||||
#define hsdb_float_state_t x86_float_state32_t
|
||||
#define HSDB_THREAD_STATE x86_THREAD_STATE32
|
||||
#define HSDB_FLOAT_STATE x86_FLOAT_STATE32
|
||||
#define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT
|
||||
#define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE32_COUNT
|
||||
#elif defined(__x86_64__)
|
||||
#define hsdb_thread_state_t x86_thread_state64_t
|
||||
#define hsdb_float_state_t x86_float_state64_t
|
||||
#define HSDB_THREAD_STATE x86_THREAD_STATE64
|
||||
#define HSDB_FLOAT_STATE x86_FLOAT_STATE64
|
||||
#define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
|
||||
#define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
|
||||
* Method: init0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) {
|
||||
symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J");
|
||||
taskID = (*env)->GetFieldID(env, cls, "task", "J");
|
||||
CHECK_EXCEPTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
|
||||
* Method: lookupByName0
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
|
||||
jlong address = 0;
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
NSString *symbolNameString = JNFJavaToNSString(env, symbolName);
|
||||
|
||||
if (debug) {
|
||||
printf("lookupInProcess called for %s\n", [symbolNameString UTF8String]);
|
||||
}
|
||||
|
||||
id symbolicator = getSymbolicator(env, this_obj);
|
||||
if (symbolicator != nil) {
|
||||
uint64_t (*dynamicCall)(id, SEL, NSString *) = (uint64_t (*)(id, SEL, NSString *))&objc_msgSend;
|
||||
address = (jlong) dynamicCall(symbolicator, @selector(addressForSymbol:), symbolNameString);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
printf("address of symbol %s = %llx\n", [symbolNameString UTF8String], address);
|
||||
}
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
|
||||
* Method: readBytesFromProcess0
|
||||
* Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
|
||||
if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes);
|
||||
|
||||
// must allocate storage instead of using former parameter buf
|
||||
jboolean isCopy;
|
||||
jbyteArray array;
|
||||
jbyte *bufPtr;
|
||||
|
||||
array = (*env)->NewByteArray(env, numBytes);
|
||||
CHECK_EXCEPTION_(0);
|
||||
|
||||
unsigned long alignedAddress;
|
||||
unsigned long alignedLength;
|
||||
kern_return_t result;
|
||||
vm_offset_t *pages;
|
||||
int *mapped;
|
||||
long pageCount;
|
||||
uint byteCount;
|
||||
int i;
|
||||
unsigned long remaining;
|
||||
|
||||
alignedAddress = trunc_page(addr);
|
||||
if (addr != alignedAddress) {
|
||||
alignedLength += addr - alignedAddress;
|
||||
}
|
||||
alignedLength = round_page(numBytes);
|
||||
pageCount = alignedLength/vm_page_size;
|
||||
|
||||
// Allocate storage for pages and flags.
|
||||
pages = malloc(pageCount * sizeof(vm_offset_t));
|
||||
mapped = calloc(pageCount, sizeof(int));
|
||||
|
||||
task_t gTask = getTask(env, this_obj);
|
||||
// Try to read each of the pages.
|
||||
for (i = 0; i < pageCount; i++) {
|
||||
result = vm_read(gTask, alignedAddress + i*vm_page_size, vm_page_size,
|
||||
&pages[i], &byteCount);
|
||||
mapped[i] = (result == KERN_SUCCESS);
|
||||
// assume all failures are unmapped pages
|
||||
}
|
||||
|
||||
if (debug) fprintf(stderr, "%ld pages\n", pageCount);
|
||||
|
||||
remaining = numBytes;
|
||||
|
||||
for (i = 0; i < pageCount; i++) {
|
||||
unsigned long len = vm_page_size;
|
||||
unsigned long start = 0;
|
||||
|
||||
if (i == 0) {
|
||||
start = addr - alignedAddress;
|
||||
len = vm_page_size - start;
|
||||
}
|
||||
|
||||
if (i == (pageCount - 1)) {
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
if (mapped[i]) {
|
||||
if (debug) fprintf(stderr, "page %d mapped (len %ld start %ld)\n", i, len, start);
|
||||
(*env)->SetByteArrayRegion(env, array, 0, len, ((jbyte *) pages[i] + start));
|
||||
vm_deallocate(mach_task_self(), pages[i], vm_page_size);
|
||||
}
|
||||
|
||||
remaining -= len;
|
||||
}
|
||||
|
||||
free (pages);
|
||||
free (mapped);
|
||||
return array;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal
|
||||
* Method: getThreadIntegerRegisterSet0
|
||||
* Signature: (I)[J
|
||||
*/
|
||||
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(JNIEnv *env, jobject this_obj, jint lwp_id) {
|
||||
if (debug)
|
||||
printf("getThreadRegisterSet0 called\n");
|
||||
|
||||
kern_return_t result;
|
||||
thread_t tid;
|
||||
mach_msg_type_number_t count = HSDB_THREAD_STATE_COUNT;
|
||||
hsdb_thread_state_t state;
|
||||
unsigned int *r;
|
||||
int i;
|
||||
jlongArray registerArray;
|
||||
jlong *primitiveArray;
|
||||
|
||||
tid = lwp_id;
|
||||
|
||||
result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count);
|
||||
|
||||
if (result != KERN_SUCCESS) {
|
||||
if (debug)
|
||||
printf("getregs: thread_get_state(%d) failed (%d)\n", tid, result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 40 32-bit registers on ppc, 16 on x86.
|
||||
// Output order is the same as the order in the ppc_thread_state/i386_thread_state struct.
|
||||
#if defined(__i386__)
|
||||
r = (unsigned int *)&state;
|
||||
registerArray = (*env)->NewLongArray(env, 8);
|
||||
primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL);
|
||||
primitiveArray[0] = r[0]; // eax
|
||||
primitiveArray[1] = r[2]; // ecx
|
||||
primitiveArray[2] = r[3]; // edx
|
||||
primitiveArray[3] = r[1]; // ebx
|
||||
primitiveArray[4] = r[7]; // esp
|
||||
primitiveArray[5] = r[6]; // ebp
|
||||
primitiveArray[6] = r[5]; // esi
|
||||
primitiveArray[7] = r[4]; // edi
|
||||
(*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0);
|
||||
#elif defined(__x86_64__)
|
||||
/* From AMD64ThreadContext.java
|
||||
public static final int R15 = 0;
|
||||
public static final int R14 = 1;
|
||||
public static final int R13 = 2;
|
||||
public static final int R12 = 3;
|
||||
public static final int R11 = 4;
|
||||
public static final int R10 = 5;
|
||||
public static final int R9 = 6;
|
||||
public static final int R8 = 7;
|
||||
public static final int RDI = 8;
|
||||
public static final int RSI = 9;
|
||||
public static final int RBP = 10;
|
||||
public static final int RBX = 11;
|
||||
public static final int RDX = 12;
|
||||
public static final int RCX = 13;
|
||||
public static final int RAX = 14;
|
||||
public static final int TRAPNO = 15;
|
||||
public static final int ERR = 16;
|
||||
public static final int RIP = 17;
|
||||
public static final int CS = 18;
|
||||
public static final int RFL = 19;
|
||||
public static final int RSP = 20;
|
||||
public static final int SS = 21;
|
||||
public static final int FS = 22;
|
||||
public static final int GS = 23;
|
||||
public static final int ES = 24;
|
||||
public static final int DS = 25;
|
||||
public static final int FSBASE = 26;
|
||||
public static final int GSBASE = 27;
|
||||
*/
|
||||
// 64 bit
|
||||
if (debug) printf("Getting threads for a 64-bit process\n");
|
||||
registerArray = (*env)->NewLongArray(env, 28);
|
||||
primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL);
|
||||
|
||||
primitiveArray[0] = state.__r15;
|
||||
primitiveArray[1] = state.__r14;
|
||||
primitiveArray[2] = state.__r13;
|
||||
primitiveArray[3] = state.__r12;
|
||||
primitiveArray[4] = state.__r11;
|
||||
primitiveArray[5] = state.__r10;
|
||||
primitiveArray[6] = state.__r9;
|
||||
primitiveArray[7] = state.__r8;
|
||||
primitiveArray[8] = state.__rdi;
|
||||
primitiveArray[9] = state.__rsi;
|
||||
primitiveArray[10] = state.__rbp;
|
||||
primitiveArray[11] = state.__rbx;
|
||||
primitiveArray[12] = state.__rdx;
|
||||
primitiveArray[13] = state.__rcx;
|
||||
primitiveArray[14] = state.__rax;
|
||||
primitiveArray[15] = 0; // trapno ?
|
||||
primitiveArray[16] = 0; // err ?
|
||||
primitiveArray[17] = state.__rip;
|
||||
primitiveArray[18] = state.__cs;
|
||||
primitiveArray[19] = state.__rflags;
|
||||
primitiveArray[20] = state.__rsp;
|
||||
primitiveArray[21] = 0; // We don't have SS
|
||||
primitiveArray[22] = state.__fs;
|
||||
primitiveArray[23] = state.__gs;
|
||||
primitiveArray[24] = 0;
|
||||
primitiveArray[25] = 0;
|
||||
primitiveArray[26] = 0;
|
||||
primitiveArray[27] = 0;
|
||||
|
||||
if (debug) printf("set registers\n");
|
||||
|
||||
(*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0);
|
||||
#else
|
||||
#error Unsupported architecture
|
||||
#endif
|
||||
|
||||
return registerArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal
|
||||
* Method: translateTID0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0(JNIEnv *env, jobject this_obj, jint tid) {
|
||||
if (debug)
|
||||
printf("translateTID0 called on tid = 0x%x\n", (int)tid);
|
||||
|
||||
kern_return_t result;
|
||||
thread_t foreign_tid, usable_tid;
|
||||
mach_msg_type_name_t type;
|
||||
|
||||
foreign_tid = tid;
|
||||
|
||||
task_t gTask = getTask(env, this_obj);
|
||||
result = mach_port_extract_right(gTask, foreign_tid,
|
||||
MACH_MSG_TYPE_COPY_SEND,
|
||||
&usable_tid, &type);
|
||||
if (result != KERN_SUCCESS)
|
||||
return -1;
|
||||
|
||||
if (debug)
|
||||
printf("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid);
|
||||
|
||||
return (jint) usable_tid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
|
||||
* Method: attach0
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(JNIEnv *env, jobject this_obj, jint jpid) {
|
||||
JNF_COCOA_ENTER(env);
|
||||
if (getenv("JAVA_SAPROC_DEBUG") != NULL)
|
||||
debug = JNI_TRUE;
|
||||
else
|
||||
debug = JNI_FALSE;
|
||||
if (debug) printf("attach0 called for jpid=%d\n", (int)jpid);
|
||||
|
||||
kern_return_t result;
|
||||
task_t gTask = 0;
|
||||
result = task_for_pid(mach_task_self(), jpid, &gTask);
|
||||
if (result != KERN_SUCCESS) {
|
||||
fprintf(stderr, "attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result);
|
||||
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
|
||||
}
|
||||
putTask(env, this_obj, gTask);
|
||||
|
||||
id symbolicator = nil;
|
||||
id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
|
||||
if (jrsSymbolicator != nil) {
|
||||
id (*dynamicCall)(id, SEL, pid_t) = (id (*)(id, SEL, pid_t))&objc_msgSend;
|
||||
symbolicator = dynamicCall(jrsSymbolicator, @selector(symbolicatorForPid:), (pid_t)jpid);
|
||||
}
|
||||
if (symbolicator != nil) {
|
||||
CFRetain(symbolicator); // pin symbolicator while in java heap
|
||||
}
|
||||
|
||||
putSymbolicator(env, this_obj, symbolicator);
|
||||
if (symbolicator == nil) {
|
||||
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process");
|
||||
}
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
|
||||
* Method: detach0
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(JNIEnv *env, jobject this_obj) {
|
||||
JNF_COCOA_ENTER(env);
|
||||
if (debug) printf("detach0 called\n");
|
||||
|
||||
task_t gTask = getTask(env, this_obj);
|
||||
mach_port_deallocate(mach_task_self(), gTask);
|
||||
id symbolicator = getSymbolicator(env, this_obj);
|
||||
if (symbolicator != nil) {
|
||||
CFRelease(symbolicator);
|
||||
}
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
@ -32,7 +32,6 @@ SOURCES = salibelf.c \
|
||||
libproc_impl.c \
|
||||
ps_proc.c \
|
||||
ps_core.c \
|
||||
hsearch_r.c \
|
||||
BsdDebuggerLocal.c
|
||||
|
||||
INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]")
|
||||
|
@ -116,7 +116,7 @@ struct symtab* build_symtab(int fd) {
|
||||
|
||||
if (shdr->sh_type == symsection) {
|
||||
ELF_SYM *syms;
|
||||
int j, n, rslt;
|
||||
int j, n;
|
||||
size_t size;
|
||||
|
||||
// FIXME: there could be multiple data buffers associated with the
|
||||
@ -138,6 +138,8 @@ struct symtab* build_symtab(int fd) {
|
||||
// manipulate the hash table.
|
||||
symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
|
||||
// guarantee(symtab->hash_table, "unexpected failure: dbopen");
|
||||
if (symtab->hash_table == NULL)
|
||||
goto bad;
|
||||
|
||||
// shdr->sh_link points to the section that contains the actual strings
|
||||
// for symbol names. the st_name field in ELF_SYM is just the
|
||||
@ -145,11 +147,15 @@ struct symtab* build_symtab(int fd) {
|
||||
// strings will not be destroyed by elf_end.
|
||||
size = scn_cache[shdr->sh_link].c_shdr->sh_size;
|
||||
symtab->strs = malloc(size);
|
||||
if (symtab->strs == NULL)
|
||||
goto bad;
|
||||
memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
|
||||
|
||||
// allocate memory for storing symbol offset and size;
|
||||
symtab->num_symbols = n;
|
||||
symtab->symbols = calloc(n , sizeof(*symtab->symbols));
|
||||
if (symtab->symbols == NULL)
|
||||
goto bad;
|
||||
|
||||
// copy symbols info our symtab and enter them info the hash table
|
||||
for (j = 0; j < n; j++, syms++) {
|
||||
@ -175,6 +181,11 @@ struct symtab* build_symtab(int fd) {
|
||||
}
|
||||
}
|
||||
}
|
||||
goto quit;
|
||||
|
||||
bad:
|
||||
destroy_symtab(symtab);
|
||||
symtab = NULL;
|
||||
|
||||
quit:
|
||||
if (shbuf) free(shbuf);
|
||||
@ -195,7 +206,7 @@ void destroy_symtab(struct symtab* symtab) {
|
||||
if (symtab->strs) free(symtab->strs);
|
||||
if (symtab->symbols) free(symtab->symbols);
|
||||
if (symtab->hash_table) {
|
||||
symtab->hash_table->close(symtab->hash_table);
|
||||
(*symtab->hash_table->close)(symtab->hash_table);
|
||||
}
|
||||
free(symtab);
|
||||
}
|
||||
@ -219,7 +230,6 @@ uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
|
||||
return rslt;
|
||||
}
|
||||
|
||||
quit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -228,12 +238,12 @@ const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
|
||||
int n = 0;
|
||||
if (!symtab) return NULL;
|
||||
for (; n < symtab->num_symbols; n++) {
|
||||
struct elf_symbol* sym = &(symtab->symbols[n]);
|
||||
if (sym->name != NULL &&
|
||||
offset >= sym->offset && offset < sym->offset + sym->size) {
|
||||
if (poffset) *poffset = (offset - sym->offset);
|
||||
return sym->name;
|
||||
}
|
||||
struct elf_symbol* sym = &(symtab->symbols[n]);
|
||||
if (sym->name != NULL &&
|
||||
offset >= sym->offset && offset < sym->offset + sym->size) {
|
||||
if (poffset) *poffset = (offset - sym->offset);
|
||||
return sym->name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
|
||||
private boolean useGCC32ABI;
|
||||
private boolean attached;
|
||||
private long p_ps_prochandle; // native debugger handle
|
||||
private long symbolicator; // macosx symbolicator handle
|
||||
private long task; // macosx task handle
|
||||
private boolean isCore;
|
||||
|
||||
// CDebugger support
|
||||
|
@ -956,7 +956,7 @@ public class SPARCFrame extends Frame {
|
||||
map.makeIntegerRegsUnsaved();
|
||||
map.shiftWindow(sp, youngerSP);
|
||||
boolean thisFrameAdjustedStack = true; // I5_savedSP is live in this RF
|
||||
return new SPARCFrame(sp, youngerSP, thisFrameAdjustedStack);
|
||||
return new SPARCFrame(biasSP(sp), biasSP(youngerSP), thisFrameAdjustedStack);
|
||||
}
|
||||
|
||||
private Frame senderForEntryFrame(RegisterMap regMap) {
|
||||
|
@ -43,7 +43,7 @@ public class PlatformInfo {
|
||||
return "bsd";
|
||||
} else if (os.equals("OpenBSD")) {
|
||||
return "bsd";
|
||||
} else if (os.equals("Darwin")) {
|
||||
} else if (os.equals("Darwin") || os.startsWith("Mac OS X")) {
|
||||
return "bsd";
|
||||
} else if (os.startsWith("Windows")) {
|
||||
return "win32";
|
||||
|
@ -471,6 +471,36 @@ copy_debug_jdk:
|
||||
($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
|
||||
fi
|
||||
|
||||
# macosx universal builds
|
||||
|
||||
ifeq ($(MACOSX_UNIVERSAL), true)
|
||||
$(UNIVERSAL_LIPO_LIST):
|
||||
lipo -create -output $@ $(EXPORT_JRE_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@)
|
||||
|
||||
$(UNIVERSAL_COPY_LIST):
|
||||
$(CP) $(EXPORT_JRE_LIB_DIR)/i386/$(subst $(EXPORT_JRE_LIB_DIR)/,,$@) $@
|
||||
|
||||
universalize: $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST)
|
||||
endif
|
||||
|
||||
universal_product:
|
||||
$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 MACOSX_UNIVERSAL=true all_product
|
||||
$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 MACOSX_UNIVERSAL=true all_product
|
||||
$(MKDIR) -p $(EXPORT_JRE_LIB_DIR)/{client,server}
|
||||
$(QUIETLY) $(MAKE) MACOSX_UNIVERSAL=true universalize
|
||||
|
||||
universal_fastdebug:
|
||||
$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 MACOSX_UNIVERSAL=true all_fastdebug
|
||||
$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 MACOSX_UNIVERSAL=true all_fastdebug
|
||||
$(MKDIR) -p $(EXPORT_JRE_LIB_DIR)/{client,server}
|
||||
$(QUIETLY) $(MAKE) MACOSX_UNIVERSAL=true universalize
|
||||
|
||||
universal_debug:
|
||||
$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 MACOSX_UNIVERSAL=true all_debug
|
||||
$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 MACOSX_UNIVERSAL=true all_debug
|
||||
$(MKDIR) -p $(EXPORT_JRE_LIB_DIR)/{client,server}
|
||||
$(QUIETLY) $(MAKE) MACOSX_UNIVERSAL=true universalize
|
||||
|
||||
#
|
||||
# Check target
|
||||
#
|
||||
@ -599,5 +629,6 @@ include $(GAMMADIR)/make/jprt.gmk
|
||||
export_product export_fastdebug export_debug export_optimized \
|
||||
export_jdk_product export_jdk_fastdebug export_jdk_debug \
|
||||
create_jdk copy_jdk update_jdk test_jdk \
|
||||
copy_product_jdk copy_fastdebug_jdk copy_debug_jdk
|
||||
copy_product_jdk copy_fastdebug_jdk copy_debug_jdk universalize \
|
||||
universal_product
|
||||
|
||||
|
@ -61,7 +61,9 @@ CPPFLAGS += -DASSERT
|
||||
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
# Compiler warnings are treated as errors
|
||||
CFLAGS_WARN = -Werror
|
||||
ifneq ($(COMPILER_WARNINGS_FATAL),false)
|
||||
CFLAGS_WARN = -Werror
|
||||
endif
|
||||
CFLAGS += $(CFLAGS_WARN)
|
||||
|
||||
OBJECTNAMES = \
|
||||
|
@ -114,10 +114,12 @@ endif
|
||||
# Get things from the platform file.
|
||||
COMPILER = $(shell sed -n 's/^compiler[ ]*=[ ]*//p' $(PLATFORM_FILE))
|
||||
|
||||
# dtracefiles is used on BSD versions that implement Dtrace (like MacOS X)
|
||||
SIMPLE_DIRS = \
|
||||
$(PLATFORM_DIR)/generated/dependencies \
|
||||
$(PLATFORM_DIR)/generated/adfiles \
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles \
|
||||
$(PLATFORM_DIR)/generated/dtracefiles
|
||||
|
||||
TARGETS = debug fastdebug jvmg optimized product profiled
|
||||
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
@ -125,7 +127,9 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
# For dependencies and recursive makes.
|
||||
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
|
||||
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
|
||||
# dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make \
|
||||
jvmti.make sa.make dtrace.make \
|
||||
env.sh env.csh jdkpath.sh .dbxrc test_gamma
|
||||
|
||||
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
|
||||
@ -155,6 +159,13 @@ ifndef HOTSPOT_VM_DISTRO
|
||||
endif
|
||||
endif
|
||||
|
||||
# MACOSX FIXME: we should be able to run test_gamma (see MACOSX_PORT-214)
|
||||
ifdef ALWAYS_PASS_TEST_GAMMA
|
||||
TEST_GAMMA_STATUS= echo 'exit 0';
|
||||
else
|
||||
TEST_GAMMA_STATUS=
|
||||
endif
|
||||
|
||||
BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION= JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
|
||||
|
||||
BUILDTREE = \
|
||||
@ -314,6 +325,16 @@ sa.make: $(BUILDTREE_MAKE)
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
dtrace.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
$(BUILDTREE_COMMENT); \
|
||||
echo; \
|
||||
echo include flags.make; \
|
||||
echo; \
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
env.sh: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
@ -390,7 +411,6 @@ test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
|
||||
echo '#!/bin/sh'; \
|
||||
$(BUILDTREE_COMMENT); \
|
||||
echo '. ./env.sh'; \
|
||||
echo "exit 0;"; \
|
||||
echo "if [ \"$(CROSS_COMPILE_ARCH)\" != \"\" ]; then { $(CROSS_COMPILING_MSG); exit 0; }; fi"; \
|
||||
echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \
|
||||
echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \
|
||||
@ -401,6 +421,7 @@ test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
|
||||
echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
|
||||
echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
|
||||
echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
|
||||
$(TEST_GAMMA_STATUS) \
|
||||
) > $@
|
||||
$(QUIETLY) chmod +x $@
|
||||
|
||||
|
@ -162,9 +162,19 @@ ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
|
||||
$(EXPORT_LIB_DIR)/sa-jdi.jar
|
||||
ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
|
||||
$(EXPORT_LIB_DIR)/sa-jdi.jar
|
||||
ADD_SA_BINARIES/universal = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
|
||||
$(EXPORT_LIB_DIR)/sa-jdi.jar
|
||||
ADD_SA_BINARIES/ppc =
|
||||
ADD_SA_BINARIES/ia64 =
|
||||
ADD_SA_BINARIES/arm =
|
||||
ADD_SA_BINARIES/zero =
|
||||
|
||||
EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH))
|
||||
|
||||
UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX)
|
||||
UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX)
|
||||
UNIVERSAL_LIPO_LIST += $(EXPORT_JRE_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX)
|
||||
|
||||
UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/server/Xusage.txt
|
||||
UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/Xusage.txt
|
||||
UNIVERSAL_COPY_LIST += $(EXPORT_JRE_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2010, 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
|
||||
@ -22,6 +22,282 @@
|
||||
#
|
||||
#
|
||||
|
||||
# Bsd does not build jvm_db
|
||||
LIBJVM_DB =
|
||||
# Rules to build jvm_db/dtrace, used by vm.make
|
||||
|
||||
# We build libjvm_dtrace/libjvm_db/dtrace for COMPILER1 and COMPILER2
|
||||
# but not for CORE or KERNEL configurations.
|
||||
|
||||
ifneq ("${TYPE}", "CORE")
|
||||
ifneq ("${TYPE}", "KERNEL")
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
# we build dtrace for macosx using USDT2 probes
|
||||
|
||||
DtraceOutDir = $(GENERATED)/dtracefiles
|
||||
|
||||
# Bsd does not build libjvm_db, does not compile on macosx
|
||||
# disabled in build: rule in vm.make
|
||||
JVM_DB = libjvm_db
|
||||
#LIBJVM_DB = libjvm_db.dylib
|
||||
LIBJVM_DB = libjvm$(G_SUFFIX)_db.dylib
|
||||
|
||||
JVM_DTRACE = jvm_dtrace
|
||||
#LIBJVM_DTRACE = libjvm_dtrace.dylib
|
||||
LIBJVM_DTRACE = libjvm$(G_SUFFIX)_dtrace.dylib
|
||||
|
||||
JVMOFFS = JvmOffsets
|
||||
JVMOFFS.o = $(JVMOFFS).o
|
||||
GENOFFS = generate$(JVMOFFS)
|
||||
|
||||
DTRACE_SRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/dtrace
|
||||
DTRACE = dtrace
|
||||
DTRACE.o = $(DTRACE).o
|
||||
|
||||
# to remove '-g' option which causes link problems
|
||||
# also '-z nodefs' is used as workaround
|
||||
GENOFFS_CFLAGS = $(shell echo $(CFLAGS) | sed -e 's/ -g / /g' -e 's/ -g0 / /g';)
|
||||
|
||||
ifdef LP64
|
||||
DTRACE_OPTS = -D_LP64
|
||||
endif
|
||||
|
||||
# making libjvm_db
|
||||
|
||||
# Use mapfile with libjvm_db.so
|
||||
LIBJVM_DB_MAPFILE = # no mapfile for usdt2 # $(MAKEFILES_DIR)/mapfile-vers-jvm_db
|
||||
#LFLAGS_JVM_DB += $(MAPFLAG:FILENAME=$(LIBJVM_DB_MAPFILE))
|
||||
|
||||
# Use mapfile with libjvm_dtrace.so
|
||||
LIBJVM_DTRACE_MAPFILE = # no mapfile for usdt2 # $(MAKEFILES_DIR)/mapfile-vers-jvm_dtrace
|
||||
#LFLAGS_JVM_DTRACE += $(MAPFLAG:FILENAME=$(LIBJVM_DTRACE_MAPFILE))
|
||||
|
||||
LFLAGS_JVM_DB += $(PICFLAG) # -D_REENTRANT
|
||||
LFLAGS_JVM_DTRACE += $(PICFLAG) # -D_REENTRANT
|
||||
|
||||
ISA = $(subst i386,i486,$(BUILDARCH))
|
||||
|
||||
# Making 64/libjvm_db.so: 64-bit version of libjvm_db.so which handles 32-bit libjvm.so
|
||||
ifneq ("${ISA}","${BUILDARCH}")
|
||||
|
||||
XLIBJVM_DB = 64/$(LIBJVM_DB)
|
||||
XLIBJVM_DB_G = 64/$(LIBJVM_DB_G)
|
||||
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
|
||||
XLIBJVM_DTRACE_G = 64/$(LIBJVM_DTRACE_G)
|
||||
XARCH = $(subst sparcv9,v9,$(shell echo $(ISA)))
|
||||
|
||||
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) mkdir -p 64/ ; \
|
||||
$(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. -I$(GENERATED) \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c #-lc
|
||||
# [ -f $(XLIBJVM_DB_G) ] || { ln -s $(LIBJVM_DB) $(XLIBJVM_DB_G); }
|
||||
|
||||
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) mkdir -p 64/ ; \
|
||||
$(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c #-lc -lthread -ldoor
|
||||
# [ -f $(XLIBJVM_DTRACE_G) ] || { ln -s $(LIBJVM_DTRACE) $(XLIBJVM_DTRACE_G); }
|
||||
|
||||
endif # ifneq ("${ISA}","${BUILDARCH}")
|
||||
|
||||
LFLAGS_GENOFFS += -L.
|
||||
|
||||
lib$(GENOFFS).dylib: $(DTRACE_SRCDIR)/$(GENOFFS).cpp $(DTRACE_SRCDIR)/$(GENOFFS).h \
|
||||
$(LIBJVM.o)
|
||||
$(QUIETLY) $(CCC) $(CPPFLAGS) $(GENOFFS_CFLAGS) $(SHARED_FLAG) $(PICFLAG) \
|
||||
$(LFLAGS_GENOFFS) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS).cpp -ljvm
|
||||
|
||||
$(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).dylib
|
||||
$(QUIETLY) $(LINK.CC) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
|
||||
./lib$(GENOFFS).dylib
|
||||
|
||||
# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
|
||||
$(JVMOFFS).h: $(GENOFFS)
|
||||
$(QUIETLY) DYLD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp; touch $@; \
|
||||
if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
|
||||
then rm -f $@; mv $@.tmp $@; \
|
||||
else rm -f $@.tmp; \
|
||||
fi
|
||||
|
||||
$(JVMOFFS)Index.h: $(GENOFFS)
|
||||
$(QUIETLY) DYLD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp; touch $@; \
|
||||
if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
|
||||
then rm -f $@; mv $@.tmp $@; \
|
||||
else rm -f $@.tmp; \
|
||||
fi
|
||||
|
||||
$(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
|
||||
$(QUIETLY) DYLD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp; touch $@; \
|
||||
if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
|
||||
then rm -f $@; mv $@.tmp $@; \
|
||||
else rm -f $@.tmp; \
|
||||
fi
|
||||
|
||||
$(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
|
||||
$(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
|
||||
|
||||
$(LIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS.o) $(XLIBJVM_DB) $(LIBJVM_DB_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. -I$(GENERATED) \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -Wall # -lc
|
||||
# [ -f $(LIBJVM_DB_G) ] || { ln -s $@ $(LIBJVM_DB_G); }
|
||||
|
||||
$(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
|
||||
@echo Making $@
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \
|
||||
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c #-lc -lthread -ldoor
|
||||
# [ -f $(LIBJVM_DTRACE_G) ] || { ln -s $@ $(LIBJVM_DTRACE_G); }
|
||||
|
||||
#$(DTRACE).d: $(DTRACE_SRCDIR)/hotspot.d $(DTRACE_SRCDIR)/hotspot_jni.d \
|
||||
# $(DTRACE_SRCDIR)/hs_private.d $(DTRACE_SRCDIR)/jhelper.d
|
||||
# $(QUIETLY) cat $^ > $@
|
||||
|
||||
$(DtraceOutDir):
|
||||
mkdir $(DtraceOutDir)
|
||||
|
||||
$(DtraceOutDir)/hotspot.h: $(DTRACE_SRCDIR)/hotspot.d | $(DtraceOutDir)
|
||||
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_SRCDIR)/hotspot.d
|
||||
|
||||
$(DtraceOutDir)/hotspot_jni.h: $(DTRACE_SRCDIR)/hotspot_jni.d | $(DtraceOutDir)
|
||||
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_SRCDIR)/hotspot_jni.d
|
||||
|
||||
$(DtraceOutDir)/hs_private.h: $(DTRACE_SRCDIR)/hs_private.d | $(DtraceOutDir)
|
||||
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_SRCDIR)/hs_private.d
|
||||
|
||||
$(DtraceOutDir)/jhelper.h: $(DTRACE_SRCDIR)/jhelper.d $(JVMOFFS).o | $(DtraceOutDir)
|
||||
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_SRCDIR)/jhelper.d
|
||||
|
||||
# jhelper currently disabled
|
||||
dtrace_gen_headers: $(DtraceOutDir)/hotspot.h $(DtraceOutDir)/hotspot_jni.h $(DtraceOutDir)/hs_private.h
|
||||
|
||||
DTraced_Files = ciEnv.o \
|
||||
classLoadingService.o \
|
||||
compileBroker.o \
|
||||
hashtable.o \
|
||||
instanceKlass.o \
|
||||
java.o \
|
||||
jni.o \
|
||||
jvm.o \
|
||||
memoryManager.o \
|
||||
nmethod.o \
|
||||
objectMonitor.o \
|
||||
runtimeService.o \
|
||||
sharedRuntime.o \
|
||||
synchronizer.o \
|
||||
thread.o \
|
||||
unsafe.o \
|
||||
vmThread.o \
|
||||
vmCMSOperations.o \
|
||||
vmPSOperations.o \
|
||||
vmGCOperations.o \
|
||||
|
||||
# Dtrace is available, so we build $(DTRACE.o)
|
||||
#$(DTRACE.o): $(DTRACE).d $(JVMOFFS).h $(JVMOFFS)Index.h $(DTraced_Files)
|
||||
# @echo Compiling $(DTRACE).d
|
||||
|
||||
# $(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \
|
||||
# $(DTraced_Files) ||\
|
||||
# STATUS=$$?;\
|
||||
# if [ x"$$STATUS" = x"1" -a \
|
||||
# x`uname -r` = x"5.10" -a \
|
||||
# x`uname -p` = x"sparc" ]; then\
|
||||
# echo "*****************************************************************";\
|
||||
# echo "* If you are building server compiler, and the error message is ";\
|
||||
# echo "* \"incorrect ELF machine type...\", you have run into solaris bug ";\
|
||||
# echo "* 6213962, \"dtrace -G doesn't work on sparcv8+ object files\".";\
|
||||
# echo "* Either patch/upgrade your system (>= S10u1_15), or set the ";\
|
||||
# echo "* environment variable HOTSPOT_DISABLE_DTRACE_PROBES to disable ";\
|
||||
# echo "* dtrace probes for this build.";\
|
||||
# echo "*****************************************************************";\
|
||||
# fi;\
|
||||
# exit $$STATUS
|
||||
# Since some DTraced_Files are in LIBJVM.o and they are touched by this
|
||||
# command, and libgenerateJvmOffsets.so depends on LIBJVM.o, 'make' will
|
||||
# think it needs to rebuild libgenerateJvmOffsets.so and thus JvmOffsets*
|
||||
# files, but it doesn't, so we touch the necessary files to prevent later
|
||||
# recompilation. Note: we only touch the necessary files if they already
|
||||
# exist in order to close a race where an empty file can be created
|
||||
# before the real build rule is executed.
|
||||
# But, we can't touch the *.h files: This rule depends
|
||||
# on them, and that would cause an infinite cycle of rebuilding.
|
||||
# Neither the *.h or *.ccp files need to be touched, since they have
|
||||
# rules which do not update them when the generator file has not
|
||||
# changed their contents.
|
||||
# $(QUIETLY) if [ -f lib$(GENOFFS).so ]; then touch lib$(GENOFFS).so; fi
|
||||
# $(QUIETLY) if [ -f $(GENOFFS) ]; then touch $(GENOFFS); fi
|
||||
# $(QUIETLY) if [ -f $(JVMOFFS.o) ]; then touch $(JVMOFFS.o); fi
|
||||
|
||||
.PHONY: dtraceCheck
|
||||
|
||||
#SYSTEM_DTRACE_H = /usr/include/dtrace.h
|
||||
SYSTEM_DTRACE_PROG = /usr/sbin/dtrace
|
||||
#PATCH_DTRACE_PROG = /opt/SUNWdtrd/sbin/dtrace
|
||||
systemDtraceFound := $(wildcard ${SYSTEM_DTRACE_PROG})
|
||||
#patchDtraceFound := $(wildcard ${PATCH_DTRACE_PROG})
|
||||
#systemDtraceHdrFound := $(wildcard $(SYSTEM_DTRACE_H))
|
||||
|
||||
#ifneq ("$(systemDtraceHdrFound)", "")
|
||||
#CFLAGS += -DHAVE_DTRACE_H
|
||||
#endif
|
||||
|
||||
#ifneq ("$(patchDtraceFound)", "")
|
||||
#DTRACE_PROG=$(PATCH_DTRACE_PROG)
|
||||
#DTRACE_INCL=-I/opt/SUNWdtrd/include
|
||||
#else
|
||||
ifneq ("$(systemDtraceFound)", "")
|
||||
DTRACE_PROG=$(SYSTEM_DTRACE_PROG)
|
||||
else
|
||||
|
||||
endif # ifneq ("$(systemDtraceFound)", "")
|
||||
#endif # ifneq ("$(patchDtraceFound)", "")
|
||||
|
||||
ifneq ("${DTRACE_PROG}", "")
|
||||
ifeq ("${HOTSPOT_DISABLE_DTRACE_PROBES}", "")
|
||||
|
||||
DTRACE_OBJS = $(DTRACE.o) #$(JVMOFFS.o)
|
||||
CFLAGS += -DDTRACE_ENABLED #$(DTRACE_INCL)
|
||||
#clangCFLAGS += -DDTRACE_ENABLED -fno-optimize-sibling-calls
|
||||
#MAPFILE_DTRACE_OPT = $(MAPFILE_DTRACE)
|
||||
|
||||
|
||||
dtraceCheck:
|
||||
|
||||
dtrace_stuff: dtrace_gen_headers
|
||||
$(QUIETLY) echo "dtrace headers generated"
|
||||
|
||||
|
||||
else # manually disabled
|
||||
|
||||
dtraceCheck:
|
||||
$(QUIETLY) echo "**NOTICE** Dtrace support disabled via environment variable"
|
||||
|
||||
dtrace_stuff:
|
||||
|
||||
endif # ifeq ("${HOTSPOT_DISABLE_DTRACE_PROBES}", "")
|
||||
|
||||
else # No dtrace program found
|
||||
|
||||
dtraceCheck:
|
||||
$(QUIETLY) echo "**NOTICE** Dtrace support disabled: not supported by system"
|
||||
|
||||
dtrace_stuff:
|
||||
|
||||
endif # ifneq ("${dtraceFound}", "")
|
||||
|
||||
endif # ifeq ($(OS_VENDOR), Darwin)
|
||||
|
||||
|
||||
else # KERNEL build
|
||||
|
||||
dtraceCheck:
|
||||
$(QUIETLY) echo "**NOTICE** Dtrace support disabled for KERNEL builds"
|
||||
|
||||
endif # ifneq ("${TYPE}", "KERNEL")
|
||||
|
||||
else # CORE build
|
||||
|
||||
dtraceCheck:
|
||||
$(QUIETLY) echo "**NOTICE** Dtrace support disabled for CORE builds"
|
||||
|
||||
endif # ifneq ("${TYPE}", "CORE")
|
||||
|
@ -30,17 +30,49 @@ OS_VENDOR = $(shell uname -s)
|
||||
# When cross-compiling the ALT_COMPILER_PATH points
|
||||
# to the cross-compilation toolset
|
||||
ifdef CROSS_COMPILE_ARCH
|
||||
CXX = $(ALT_COMPILER_PATH)/g++
|
||||
CPP = $(ALT_COMPILER_PATH)/g++
|
||||
CC = $(ALT_COMPILER_PATH)/gcc
|
||||
HOSTCPP = g++
|
||||
HOSTCC = gcc
|
||||
else
|
||||
CXX ?= g++
|
||||
CPP = $(CXX)
|
||||
CC ?= gcc
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CPP)
|
||||
CPP = $(ALT_COMPILER_PATH)/g++
|
||||
CC = $(ALT_COMPILER_PATH)/gcc
|
||||
HOSTCPP = g++
|
||||
HOSTCC = gcc
|
||||
else ifneq ($(OS_VENDOR), Darwin)
|
||||
CXX = g++
|
||||
CPP = $(CXX)
|
||||
CC = gcc
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CC)
|
||||
endif
|
||||
|
||||
# i486 hotspot requires -mstackrealign on Darwin.
|
||||
# llvm-gcc supports this in Xcode 3.2.6 and 4.0.
|
||||
# gcc-4.0 supports this on earlier versions.
|
||||
# Prefer llvm-gcc where available.
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
ifeq ($(origin CXX), default)
|
||||
CXX = llvm-g++
|
||||
endif
|
||||
ifeq ($(origin CC), default)
|
||||
CC = llvm-gcc
|
||||
endif
|
||||
CPP = $(CXX)
|
||||
|
||||
ifeq ($(ARCH), i486)
|
||||
LLVM_SUPPORTS_STACKREALIGN := $(shell \
|
||||
[ "0"`llvm-gcc -v 2>&1 | grep LLVM | sed -E "s/.*LLVM build ([0-9]+).*/\1/"` -gt "2333" ] \
|
||||
&& echo true || echo false)
|
||||
|
||||
ifeq ($(LLVM_SUPPORTS_STACKREALIGN), true)
|
||||
CXX32 ?= llvm-g++
|
||||
CC32 ?= llvm-gcc
|
||||
else
|
||||
CXX32 ?= g++-4.0
|
||||
CC32 ?= gcc-4.0
|
||||
endif
|
||||
CPP = $(CXX32)
|
||||
CC = $(CC32)
|
||||
endif
|
||||
|
||||
HOSTCPP = $(CPP)
|
||||
HOSTCC = $(CC)
|
||||
endif
|
||||
|
||||
AS = $(CC) -c -x assembler-with-cpp
|
||||
@ -130,7 +162,9 @@ else
|
||||
endif
|
||||
|
||||
# Compiler warnings are treated as errors
|
||||
WARNINGS_ARE_ERRORS = -Werror
|
||||
ifneq ($(COMPILER_WARNINGS_FATAL),false)
|
||||
WARNINGS_ARE_ERRORS = -Werror
|
||||
endif
|
||||
|
||||
# Except for a few acceptable ones
|
||||
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
|
||||
@ -152,7 +186,13 @@ endif
|
||||
|
||||
|
||||
# The flags to use for an Optimized g++ build
|
||||
OPT_CFLAGS += -O3
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
# use -Os by default, unless -O3 can be proved to be worth the cost, as per policy
|
||||
# <http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port+Compilers>
|
||||
OPT_CFLAGS += -Os
|
||||
else
|
||||
OPT_CFLAGS += -O3
|
||||
endif
|
||||
|
||||
# Hotspot uses very unstrict aliasing turn this optimization off
|
||||
OPT_CFLAGS += -fno-strict-aliasing
|
||||
@ -212,7 +252,7 @@ ifeq ($(OS_VENDOR), Darwin)
|
||||
SONAMEFLAG =
|
||||
|
||||
# Build shared library
|
||||
SHARED_FLAG = -dynamiclib $(VM_PICFLAG)
|
||||
SHARED_FLAG = -Wl,-install_name,@rpath/$(@F) -dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $(VM_PICFLAG)
|
||||
|
||||
# Keep symbols even they are not used
|
||||
#AOUT_FLAGS += -Xlinker -export-dynamic
|
||||
|
@ -38,18 +38,16 @@ TOPDIR = $(shell echo `pwd`)
|
||||
GENERATED = $(TOPDIR)/../generated
|
||||
|
||||
# tools.jar is needed by the JDI - SA binding
|
||||
SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar
|
||||
ifeq ($(SA_APPLE_BOOT_JAVA),true)
|
||||
SA_CLASSPATH = $(BOOT_JAVA_HOME)/bundle/Classes/classes.jar
|
||||
else
|
||||
SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar
|
||||
endif
|
||||
|
||||
# TODO: if it's a modules image, check if SA module is installed.
|
||||
MODULELIB_PATH= $(BOOT_JAVA_HOME)/lib/modules
|
||||
|
||||
# gnumake 3.78.1 does not accept the *s that
|
||||
# are in AGENT_FILES1 and AGENT_FILES2, so use the shell to expand them
|
||||
AGENT_FILES1 := $(shell /bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1))
|
||||
AGENT_FILES2 := $(shell /bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2))
|
||||
|
||||
AGENT_FILES1_LIST := $(GENERATED)/agent1.classes.list
|
||||
AGENT_FILES2_LIST := $(GENERATED)/agent2.classes.list
|
||||
AGENT_FILES_LIST := $(GENERATED)/agent.classes.list
|
||||
|
||||
SA_CLASSDIR = $(GENERATED)/saclasses
|
||||
|
||||
@ -68,7 +66,7 @@ all:
|
||||
$(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
|
||||
fi
|
||||
|
||||
$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
|
||||
$(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
|
||||
$(QUIETLY) echo "Making $@"
|
||||
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
|
||||
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
|
||||
@ -82,7 +80,6 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
|
||||
$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
|
||||
mkdir -p $(SA_CLASSDIR); \
|
||||
fi
|
||||
|
||||
# Note: When indented, make tries to execute the '$(shell' comment.
|
||||
# In some environments, cmd processors have limited line length.
|
||||
# To prevent the javac invocation in the next block from using
|
||||
@ -93,13 +90,12 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
|
||||
# the initialization of the lists is also done in the same phase
|
||||
# using '$(shell rm ...' instead of using the more traditional
|
||||
# 'rm ...' rule.
|
||||
$(shell rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST))
|
||||
$(foreach file,$(AGENT_FILES1),$(shell echo $(file) >> $(AGENT_FILES1_LIST)))
|
||||
$(foreach file,$(AGENT_FILES2),$(shell echo $(file) >> $(AGENT_FILES2_LIST)))
|
||||
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
|
||||
|
||||
$(shell rm -rf $(AGENT_FILES_LIST))
|
||||
# gnumake 3.78.1 does not accept the *'s that
|
||||
# are in AGENT_FILES, so use the shell to expand them.
|
||||
# Be extra carefull to not produce too long command lines in the shell!
|
||||
$(foreach file,$(AGENT_FILES),$(shell ls -1 $(file) >> $(AGENT_FILES_LIST)))
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES_LIST)
|
||||
$(QUIETLY) $(REMOTE) $(COMPILE.RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
|
||||
$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
|
||||
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
|
||||
@ -118,4 +114,4 @@ $(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
|
||||
clean:
|
||||
rm -rf $(SA_CLASSDIR)
|
||||
rm -rf $(GENERATED)/sa-jdi.jar
|
||||
rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
|
||||
rm -rf $(AGENT_FILES_LIST)
|
||||
|
@ -40,20 +40,29 @@ AGENT_DIR = $(GAMMADIR)/agent
|
||||
|
||||
SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family)
|
||||
|
||||
# disable building saproc until hsearch_r license issues are resolved
|
||||
#ifeq ($(OS_VENDOR), FreeBSD)
|
||||
#SASRCFILES = $(SASRCDIR)/salibelf.c \
|
||||
# $(SASRCDIR)/symtab.c \
|
||||
# $(SASRCDIR)/libproc_impl.c \
|
||||
# $(SASRCDIR)/ps_proc.c \
|
||||
# $(SASRCDIR)/ps_core.c \
|
||||
# $(SASRCDIR)/hsearch_r.c \
|
||||
# $(SASRCDIR)/BsdDebuggerLocal.c
|
||||
#SALIBS = -lutil -lthread_db
|
||||
#else
|
||||
SASRCFILES = $(SASRCDIR)/StubDebuggerLocal.c
|
||||
SALIBS =
|
||||
#endif
|
||||
NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c \
|
||||
$(SASRCDIR)/symtab.c \
|
||||
$(SASRCDIR)/libproc_impl.c \
|
||||
$(SASRCDIR)/ps_proc.c \
|
||||
$(SASRCDIR)/ps_core.c \
|
||||
$(SASRCDIR)/BsdDebuggerLocal.c
|
||||
|
||||
ifeq ($(OS_VENDOR), FreeBSD)
|
||||
SASRCFILES = $(NON_STUB_SASRCFILES)
|
||||
SALIBS = -lutil -lthread_db
|
||||
SAARCH = $(ARCHFLAG)
|
||||
else
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
SASRCFILES = $(SASRCDIR)/MacosxDebuggerLocal.m
|
||||
SALIBS = -g -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation
|
||||
#objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles?
|
||||
SAARCH = $(subst -march=i586,,$(ARCHFLAG))
|
||||
else
|
||||
SASRCFILES = $(SASRCDIR)/StubDebuggerLocal.c
|
||||
SALIBS =
|
||||
SAARCH = $(ARCHFLAG)
|
||||
endif
|
||||
endif
|
||||
|
||||
SAMAPFILE = $(SASRCDIR)/mapfile
|
||||
|
||||
@ -79,6 +88,15 @@ SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE))
|
||||
endif
|
||||
SA_LFLAGS += $(LDFLAGS_HASH_STYLE)
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
BOOT_JAVA_INCLUDES = -I$(BOOT_JAVA_HOME)/include \
|
||||
-I$(BOOT_JAVA_HOME)/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") \
|
||||
-I/System/Library/Frameworks/JavaVM.framework/Headers
|
||||
else
|
||||
BOOT_JAVA_INCLUDES = -I$(BOOT_JAVA_HOME)/include \
|
||||
-I$(BOOT_JAVA_HOME)/include/$(shell uname -s | tr "[:upper:]" "[:lower:]")
|
||||
endif
|
||||
|
||||
$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
|
||||
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
|
||||
@ -86,11 +104,10 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
fi
|
||||
@echo Making SA debugger back-end...
|
||||
$(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \
|
||||
$(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
||||
$(SYMFLAG) $(SAARCH) $(SHARED_FLAG) $(PICFLAG) \
|
||||
-I$(SASRCDIR) \
|
||||
-I$(GENERATED) \
|
||||
-I$(BOOT_JAVA_HOME)/include \
|
||||
-I$(BOOT_JAVA_HOME)/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") \
|
||||
$(BOOT_JAVA_INCLUDES) \
|
||||
$(SASRCFILES) \
|
||||
$(SA_LFLAGS) \
|
||||
$(SA_DEBUG_CFLAGS) \
|
||||
|
@ -82,7 +82,7 @@ default: vm_build_preliminaries the_vm
|
||||
@echo All done.
|
||||
|
||||
# This is an explicit dependency for the sake of parallel makes.
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff dtrace_stuff
|
||||
@# We need a null action here, so implicit rules don't get consulted.
|
||||
|
||||
$(Cached_plat): $(Plat_File)
|
||||
@ -96,6 +96,15 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
# generate dtrace header files
|
||||
dtrace_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f dtrace.make dtrace_stuff $(MFLAGS-adjusted) GENERATED=$(GENERATED)
|
||||
else
|
||||
dtrace_stuff:
|
||||
@# We need a null action here, so implicit rules don't get consulted.
|
||||
endif
|
||||
|
||||
# generate SA jar files and native header
|
||||
sa_stuff:
|
||||
@$(MAKE) -f sa.make $(MFLAGS-adjusted)
|
||||
|
@ -108,6 +108,7 @@ LFLAGS += $(EXTRA_CFLAGS)
|
||||
|
||||
# Don't set excutable bit on stack segment
|
||||
# the same could be done by separate execstack command
|
||||
# Darwin is non-executable-stack by default
|
||||
ifneq ($(OS_VENDOR), Darwin)
|
||||
LFLAGS += -Xlinker -z -Xlinker noexecstack
|
||||
endif
|
||||
@ -322,7 +323,16 @@ include $(MAKEFILES_DIR)/saproc.make
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
$(LIBJVM).dSYM: $(LIBJVM)
|
||||
dsymutil $(LIBJVM)
|
||||
|
||||
# no launcher or libjvm_db for macosx
|
||||
build: $(LIBJVM) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
|
||||
echo "Doing vm.make build:"
|
||||
else
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
|
||||
endif
|
||||
|
||||
install: install_jvm install_jsig install_saproc
|
||||
|
||||
|
@ -281,6 +281,13 @@ EXPORT_JRE_BIN_DIR = $(EXPORT_JRE_DIR)/bin
|
||||
EXPORT_JRE_LIB_DIR = $(EXPORT_JRE_DIR)/lib
|
||||
EXPORT_JRE_LIB_ARCH_DIR = $(EXPORT_JRE_LIB_DIR)/$(LIBARCH)
|
||||
|
||||
# non-universal macosx builds need to appear universal
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
ifneq ($(MACOSX_UNIVERSAL), true)
|
||||
EXPORT_JRE_LIB_ARCH_DIR = $(EXPORT_JRE_LIB_DIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Common export list of files
|
||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmti.h
|
||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmticmlr.h
|
||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
|
||||
|
||||
HS_MAJOR_VER=23
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=02
|
||||
HS_BUILD_NUMBER=03
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=8
|
||||
|
@ -1,28 +0,0 @@
|
||||
Copyright (c) %YEARS%, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of Oracle nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2011, 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
|
||||
@ -82,13 +82,35 @@ static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
|
||||
}
|
||||
|
||||
static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
|
||||
// FIXME
|
||||
(void)memmove(to, from, count << LogBytesPerShort);
|
||||
if (from > to) {
|
||||
while (count-- > 0) {
|
||||
// Copy forwards
|
||||
*to++ = *from++;
|
||||
}
|
||||
} else {
|
||||
from += count - 1;
|
||||
to += count - 1;
|
||||
while (count-- > 0) {
|
||||
// Copy backwards
|
||||
*to-- = *from--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
|
||||
// FIXME
|
||||
(void)memmove(to, from, count << LogBytesPerInt);
|
||||
if (from > to) {
|
||||
while (count-- > 0) {
|
||||
// Copy forwards
|
||||
*to++ = *from++;
|
||||
}
|
||||
} else {
|
||||
from += count - 1;
|
||||
to += count - 1;
|
||||
while (count-- > 0) {
|
||||
// Copy backwards
|
||||
*to-- = *from--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
|
||||
|
@ -10476,7 +10476,7 @@ instruct countTrailingZerosI(iRegI dst, iRegI src, flagsReg cr) %{
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{
|
||||
instruct countTrailingZerosL(iRegIsafe dst, iRegL src, flagsReg cr) %{
|
||||
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
|
||||
match(Set dst (CountTrailingZerosL src));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
@ -232,11 +232,13 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
|
||||
void frame::patch_pc(Thread* thread, address pc) {
|
||||
address* pc_addr = &(((address*) sp())[-1]);
|
||||
if (TracePcPatching) {
|
||||
tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ",
|
||||
&((address *)sp())[-1], ((address *)sp())[-1], pc);
|
||||
tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ",
|
||||
pc_addr, *pc_addr, pc);
|
||||
}
|
||||
((address *)sp())[-1] = pc;
|
||||
assert(_pc == *pc_addr, err_msg("must be: " INTPTR_FORMAT " == " INTPTR_FORMAT, _pc, *pc_addr));
|
||||
*pc_addr = pc;
|
||||
_cb = CodeCache::find_blob(pc);
|
||||
address original_pc = nmethod::get_deopt_original_pc(this);
|
||||
if (original_pc != NULL) {
|
||||
@ -671,4 +673,3 @@ intptr_t *frame::initial_deoptimization_info() {
|
||||
// used to reset the saved FP
|
||||
return fp();
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,14 @@
|
||||
|
||||
#define JNICALL
|
||||
typedef int jint;
|
||||
|
||||
#ifdef _LP64
|
||||
#if defined(_LP64) && !defined(__APPLE__)
|
||||
typedef long jlong;
|
||||
#else
|
||||
/*
|
||||
* On _LP64 __APPLE__ "long" and "long long" are both 64 bits,
|
||||
* but we use the "long long" typedef to avoid complaints from
|
||||
* the __APPLE__ compiler about fprintf formats.
|
||||
*/
|
||||
typedef long long jlong;
|
||||
#endif
|
||||
|
||||
|
@ -410,8 +410,8 @@ void MethodHandles::RicochetFrame::verify_offsets() {
|
||||
|
||||
void MethodHandles::RicochetFrame::verify() const {
|
||||
verify_offsets();
|
||||
assert(magic_number_1() == MAGIC_NUMBER_1, "");
|
||||
assert(magic_number_2() == MAGIC_NUMBER_2, "");
|
||||
assert(magic_number_1() == MAGIC_NUMBER_1, err_msg(PTR_FORMAT " == " PTR_FORMAT, magic_number_1(), MAGIC_NUMBER_1));
|
||||
assert(magic_number_2() == MAGIC_NUMBER_2, err_msg(PTR_FORMAT " == " PTR_FORMAT, magic_number_2(), MAGIC_NUMBER_2));
|
||||
if (!Universe::heap()->is_gc_active()) {
|
||||
if (saved_args_layout() != NULL) {
|
||||
assert(saved_args_layout()->is_method(), "must be valid oop");
|
||||
|
@ -132,7 +132,10 @@ class RicochetFrame {
|
||||
intptr_t* sender_link() const { return _sender_link; }
|
||||
address sender_pc() const { return _sender_pc; }
|
||||
|
||||
intptr_t* extended_sender_sp() const { return saved_args_base(); }
|
||||
intptr_t* extended_sender_sp() const {
|
||||
// The extended sender SP is above the current RicochetFrame.
|
||||
return (intptr_t*) (((address) this) + sizeof(RicochetFrame));
|
||||
}
|
||||
|
||||
intptr_t return_value_slot_number() const {
|
||||
return adapter_conversion_vminfo(conversion());
|
||||
|
294
hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp
Normal file
294
hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is to provide sanity check in jhelper.d which compares SCCS
|
||||
* versions of generateJvmOffsets.cpp used to create and extract
|
||||
* contents of __JvmOffsets[] table.
|
||||
* The __JvmOffsets[] table is located in generated JvmOffsets.cpp.
|
||||
*
|
||||
* GENOFFS_SCCS_VER 34
|
||||
*/
|
||||
|
||||
#include "generateJvmOffsets.h"
|
||||
|
||||
/* A workaround for private and protected fields */
|
||||
#define private public
|
||||
#define protected public
|
||||
|
||||
// not on macosx #include <proc_service.h>
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "code/pcDesc.hpp"
|
||||
#include "gc_interface/collectedHeap.hpp"
|
||||
#include "memory/heap.hpp"
|
||||
#include "memory/memRegion.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/constMethodOop.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/methodOop.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
#include "runtime/virtualspace.hpp"
|
||||
#include "runtime/vmStructs.hpp"
|
||||
#include "utilities/accessFlags.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
// These are defined somewhere for Solaris
|
||||
#define PR_MODEL_ILP32 1
|
||||
#define PR_MODEL_LP64 2
|
||||
|
||||
#ifdef COMPILER1
|
||||
#if defined(DEBUG) || defined(FASTDEBUG)
|
||||
|
||||
/*
|
||||
* To avoid the most part of potential link errors
|
||||
* we link this program with -z nodefs .
|
||||
*
|
||||
* But for 'debug1' and 'fastdebug1' we still have to provide
|
||||
* a particular workaround for the following symbols bellow.
|
||||
* It will be good to find out a generic way in the future.
|
||||
*/
|
||||
|
||||
#pragma weak tty
|
||||
#pragma weak CMSExpAvgFactor
|
||||
|
||||
#if defined(i386) || defined(__i386) || defined(__amd64)
|
||||
#pragma weak noreg
|
||||
#endif /* i386 */
|
||||
|
||||
LIR_Opr LIR_OprFact::illegalOpr = (LIR_Opr) 0;
|
||||
|
||||
address StubRoutines::_call_stub_return_address = NULL;
|
||||
|
||||
StubQueue* AbstractInterpreter::_code = NULL;
|
||||
|
||||
#endif /* defined(DEBUG) || defined(FASTDEBUG) */
|
||||
#endif /* COMPILER1 */
|
||||
|
||||
#define GEN_OFFS(Type,Name) \
|
||||
switch(gen_variant) { \
|
||||
case GEN_OFFSET: \
|
||||
printf("#define OFFSET_%-33s %ld\n", \
|
||||
#Type #Name, offset_of(Type, Name)); \
|
||||
break; \
|
||||
case GEN_INDEX: \
|
||||
printf("#define IDX_OFFSET_%-33s %d\n", \
|
||||
#Type #Name, index++); \
|
||||
break; \
|
||||
case GEN_TABLE: \
|
||||
printf("\tOFFSET_%s,\n", #Type #Name); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GEN_SIZE(Type) \
|
||||
switch(gen_variant) { \
|
||||
case GEN_OFFSET: \
|
||||
printf("#define SIZE_%-35s %ld\n", \
|
||||
#Type, sizeof(Type)); \
|
||||
break; \
|
||||
case GEN_INDEX: \
|
||||
printf("#define IDX_SIZE_%-35s %d\n", \
|
||||
#Type, index++); \
|
||||
break; \
|
||||
case GEN_TABLE: \
|
||||
printf("\tSIZE_%s,\n", #Type); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define GEN_VALUE(String,Value) \
|
||||
switch(gen_variant) { \
|
||||
case GEN_OFFSET: \
|
||||
printf("#define %-40s %d\n", #String, Value); \
|
||||
break; \
|
||||
case GEN_INDEX: \
|
||||
printf("#define IDX_%-40s %d\n", #String, index++); \
|
||||
break; \
|
||||
case GEN_TABLE: \
|
||||
printf("\t" #String ",\n"); \
|
||||
break; \
|
||||
}
|
||||
|
||||
void gen_prologue(GEN_variant gen_variant) {
|
||||
const char *suffix;
|
||||
|
||||
switch(gen_variant) {
|
||||
case GEN_OFFSET: suffix = ".h"; break;
|
||||
case GEN_INDEX: suffix = "Index.h"; break;
|
||||
case GEN_TABLE: suffix = ".cpp"; break;
|
||||
}
|
||||
|
||||
printf("/*\n");
|
||||
printf(" * JvmOffsets%s !!!DO NOT EDIT!!! \n", suffix);
|
||||
printf(" * The generateJvmOffsets program generates this file!\n");
|
||||
printf(" */\n\n");
|
||||
switch(gen_variant) {
|
||||
|
||||
case GEN_OFFSET:
|
||||
case GEN_INDEX:
|
||||
break;
|
||||
|
||||
case GEN_TABLE:
|
||||
printf("#include \"JvmOffsets.h\"\n");
|
||||
printf("\n");
|
||||
printf("int __JvmOffsets[] = {\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gen_epilogue(GEN_variant gen_variant) {
|
||||
if (gen_variant != GEN_TABLE) {
|
||||
return;
|
||||
}
|
||||
printf("};\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int generateJvmOffsets(GEN_variant gen_variant) {
|
||||
int index = 0; /* It is used to generate JvmOffsetsIndex.h */
|
||||
int pointer_size = sizeof(void *);
|
||||
int data_model = (pointer_size == 4) ? PR_MODEL_ILP32 : PR_MODEL_LP64;
|
||||
|
||||
gen_prologue(gen_variant);
|
||||
|
||||
GEN_VALUE(DATA_MODEL, data_model);
|
||||
GEN_VALUE(POINTER_SIZE, pointer_size);
|
||||
#if defined(TIERED)
|
||||
GEN_VALUE(COMPILER, 3);
|
||||
#elif COMPILER1
|
||||
GEN_VALUE(COMPILER, 1);
|
||||
#elif COMPILER2
|
||||
GEN_VALUE(COMPILER, 2);
|
||||
#else
|
||||
GEN_VALUE(COMPILER, 0);
|
||||
#endif // COMPILER1 && COMPILER2
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(CollectedHeap, _reserved);
|
||||
GEN_OFFS(MemRegion, _start);
|
||||
GEN_OFFS(MemRegion, _word_size);
|
||||
GEN_SIZE(HeapWord);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(VMStructEntry, typeName);
|
||||
GEN_OFFS(VMStructEntry, fieldName);
|
||||
GEN_OFFS(VMStructEntry, address);
|
||||
GEN_SIZE(VMStructEntry);
|
||||
printf("\n");
|
||||
|
||||
GEN_VALUE(MAX_METHOD_CODE_SIZE, max_method_code_size);
|
||||
#if defined(sparc) || defined(__sparc)
|
||||
GEN_VALUE(OFFSET_interpreter_frame_method, 2 * pointer_size); /* L2 in saved window */
|
||||
GEN_VALUE(OFFSET_interpreter_frame_sender_sp, 13 * pointer_size); /* I5 in saved window */
|
||||
// Fake value for consistency. It is not going to be used.
|
||||
GEN_VALUE(OFFSET_interpreter_frame_bcx_offset, 0xFFFF);
|
||||
#elif defined(i386) || defined(__i386) || defined(__amd64)
|
||||
GEN_VALUE(OFFSET_interpreter_frame_sender_sp, -1 * pointer_size);
|
||||
GEN_VALUE(OFFSET_interpreter_frame_method, -3 * pointer_size);
|
||||
GEN_VALUE(OFFSET_interpreter_frame_bcx_offset, -7 * pointer_size);
|
||||
#endif
|
||||
|
||||
GEN_OFFS(Klass, _name);
|
||||
GEN_OFFS(constantPoolOopDesc, _pool_holder);
|
||||
printf("\n");
|
||||
|
||||
GEN_VALUE(OFFSET_HeapBlockHeader_used, (int) offset_of(HeapBlock::Header, _used));
|
||||
GEN_OFFS(oopDesc, _metadata);
|
||||
printf("\n");
|
||||
|
||||
GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE);
|
||||
GEN_VALUE(constMethodOopDesc_has_linenumber_table, constMethodOopDesc::_has_linenumber_table);
|
||||
GEN_OFFS(AccessFlags, _flags);
|
||||
GEN_OFFS(Symbol, _length);
|
||||
GEN_OFFS(Symbol, _body);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(methodOopDesc, _constMethod);
|
||||
GEN_OFFS(methodOopDesc, _constants);
|
||||
GEN_OFFS(methodOopDesc, _access_flags);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(constMethodOopDesc, _flags);
|
||||
GEN_OFFS(constMethodOopDesc, _code_size);
|
||||
GEN_OFFS(constMethodOopDesc, _name_index);
|
||||
GEN_OFFS(constMethodOopDesc, _signature_index);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(CodeHeap, _memory);
|
||||
GEN_OFFS(CodeHeap, _segmap);
|
||||
GEN_OFFS(CodeHeap, _log2_segment_size);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(VirtualSpace, _low_boundary);
|
||||
GEN_OFFS(VirtualSpace, _high_boundary);
|
||||
GEN_OFFS(VirtualSpace, _low);
|
||||
GEN_OFFS(VirtualSpace, _high);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(CodeBlob, _name);
|
||||
GEN_OFFS(CodeBlob, _header_size);
|
||||
GEN_OFFS(CodeBlob, _content_offset);
|
||||
GEN_OFFS(CodeBlob, _code_offset);
|
||||
GEN_OFFS(CodeBlob, _data_offset);
|
||||
GEN_OFFS(CodeBlob, _frame_size);
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(nmethod, _method);
|
||||
GEN_OFFS(nmethod, _oops_offset);
|
||||
GEN_OFFS(nmethod, _scopes_data_offset);
|
||||
GEN_OFFS(nmethod, _scopes_pcs_offset);
|
||||
GEN_OFFS(nmethod, _handler_table_offset);
|
||||
GEN_OFFS(nmethod, _deoptimize_offset);
|
||||
GEN_OFFS(nmethod, _orig_pc_offset);
|
||||
|
||||
GEN_OFFS(PcDesc, _pc_offset);
|
||||
GEN_OFFS(PcDesc, _scope_decode_offset);
|
||||
|
||||
printf("\n");
|
||||
|
||||
GEN_OFFS(NarrowOopStruct, _base);
|
||||
GEN_OFFS(NarrowOopStruct, _shift);
|
||||
printf("\n");
|
||||
|
||||
GEN_VALUE(SIZE_HeapBlockHeader, (int) sizeof(HeapBlock::Header));
|
||||
GEN_SIZE(oopDesc);
|
||||
GEN_SIZE(constantPoolOopDesc);
|
||||
printf("\n");
|
||||
|
||||
GEN_SIZE(PcDesc);
|
||||
GEN_SIZE(methodOopDesc);
|
||||
GEN_SIZE(constMethodOopDesc);
|
||||
GEN_SIZE(nmethod);
|
||||
GEN_SIZE(CodeBlob);
|
||||
GEN_SIZE(BufferBlob);
|
||||
GEN_SIZE(SingletonBlob);
|
||||
GEN_SIZE(RuntimeStub);
|
||||
GEN_SIZE(SafepointBlob);
|
||||
|
||||
gen_epilogue(gen_variant);
|
||||
printf("\n");
|
||||
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
43
hotspot/src/os/bsd/dtrace/generateJvmOffsets.h
Normal file
43
hotspot/src/os/bsd/dtrace/generateJvmOffsets.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_SOLARIS_DTRACE_GENERATEJVMOFFSETS_H
|
||||
#define OS_SOLARIS_DTRACE_GENERATEJVMOFFSETS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
typedef enum GEN_variant {
|
||||
GEN_OFFSET = 0,
|
||||
GEN_INDEX = 1,
|
||||
GEN_TABLE = 2
|
||||
} GEN_variant;
|
||||
|
||||
extern "C" {
|
||||
int generateJvmOffsets(GEN_variant gen_var);
|
||||
void gen_prologue(GEN_variant gen_var);
|
||||
void gen_epilogue(GEN_variant gen_var);
|
||||
}
|
||||
|
||||
#endif // OS_SOLARIS_DTRACE_GENERATEJVMOFFSETS_H
|
53
hotspot/src/os/bsd/dtrace/generateJvmOffsetsMain.c
Normal file
53
hotspot/src/os/bsd/dtrace/generateJvmOffsetsMain.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "generateJvmOffsets.h"
|
||||
|
||||
const char *HELP =
|
||||
"HELP: generateJvmOffsets {-header | -index | -table} \n";
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
GEN_variant gen_var;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("%s", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 == strcmp(argv[1], "-header")) {
|
||||
gen_var = GEN_OFFSET;
|
||||
}
|
||||
else if (0 == strcmp(argv[1], "-index")) {
|
||||
gen_var = GEN_INDEX;
|
||||
}
|
||||
else if (0 == strcmp(argv[1], "-table")) {
|
||||
gen_var = GEN_TABLE;
|
||||
}
|
||||
else {
|
||||
printf("%s", HELP);
|
||||
return 1;
|
||||
}
|
||||
return generateJvmOffsets(gen_var);
|
||||
}
|
86
hotspot/src/os/bsd/dtrace/hotspot.d
Normal file
86
hotspot/src/os/bsd/dtrace/hotspot.d
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
provider hotspot {
|
||||
probe class__loaded(char*, uintptr_t, void*, uintptr_t);
|
||||
probe class__unloaded(char*, uintptr_t, void*, uintptr_t);
|
||||
probe class__initialization__required(char*, uintptr_t, void*, intptr_t);
|
||||
probe class__initialization__recursive(char*, uintptr_t, void*, intptr_t,int);
|
||||
probe class__initialization__concurrent(char*, uintptr_t, void*, intptr_t,int);
|
||||
probe class__initialization__erroneous(char*, uintptr_t, void*, intptr_t, int);
|
||||
probe class__initialization__super__failed(char*, uintptr_t, void*, intptr_t,int);
|
||||
probe class__initialization__clinit(char*, uintptr_t, void*, intptr_t,int);
|
||||
probe class__initialization__error(char*, uintptr_t, void*, intptr_t,int);
|
||||
probe class__initialization__end(char*, uintptr_t, void*, intptr_t,int);
|
||||
probe vm__init__begin();
|
||||
probe vm__init__end();
|
||||
probe vm__shutdown();
|
||||
probe vmops__request(char*, uintptr_t, int);
|
||||
probe vmops__begin(char*, uintptr_t, int);
|
||||
probe vmops__end(char*, uintptr_t, int);
|
||||
probe gc__begin(uintptr_t);
|
||||
probe gc__end();
|
||||
probe mem__pool__gc__begin(
|
||||
char*, uintptr_t, char*, uintptr_t,
|
||||
uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
probe mem__pool__gc__end(
|
||||
char*, uintptr_t, char*, uintptr_t,
|
||||
uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
probe thread__probe__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
probe thread__probe__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
probe thread__sleep__begin(long long);
|
||||
probe thread__sleep__end(int);
|
||||
probe thread__yield();
|
||||
probe thread__park__begin(uintptr_t, int, long long);
|
||||
probe thread__park__end(uintptr_t);
|
||||
probe thread__unpark(uintptr_t);
|
||||
probe method__compile__begin(
|
||||
const char*, uintptr_t, const char*, uintptr_t, const char*, uintptr_t, const char*, uintptr_t);
|
||||
probe method__compile__end(
|
||||
char*, uintptr_t, char*, uintptr_t, char*, uintptr_t,
|
||||
char*, uintptr_t, uintptr_t);
|
||||
probe compiled__method__load(
|
||||
char*, uintptr_t, char*, uintptr_t, char*, uintptr_t, void*, uintptr_t);
|
||||
probe compiled__method__unload(
|
||||
char*, uintptr_t, char*, uintptr_t, char*, uintptr_t);
|
||||
probe monitor__contended__enter(uintptr_t, uintptr_t, char*, uintptr_t);
|
||||
probe monitor__contended__entered(uintptr_t, uintptr_t, char*, uintptr_t);
|
||||
probe monitor__contended__exit(uintptr_t, uintptr_t, char*, uintptr_t);
|
||||
probe monitor__wait(uintptr_t, uintptr_t, char*, uintptr_t, uintptr_t);
|
||||
probe monitor__probe__waited(uintptr_t, uintptr_t, char*, uintptr_t);
|
||||
probe monitor__notify(uintptr_t, uintptr_t, char*, uintptr_t);
|
||||
probe monitor__notifyAll(uintptr_t, uintptr_t, char*, uintptr_t);
|
||||
|
||||
probe object__alloc(int, char*, uintptr_t, uintptr_t);
|
||||
probe method__entry(
|
||||
int, char*, int, char*, int, char*, int);
|
||||
probe method__return(
|
||||
int, char*, int, char*, int, char*, int);
|
||||
};
|
||||
|
||||
#pragma D attributes Evolving/Evolving/Common provider hotspot provider
|
||||
#pragma D attributes Private/Private/Unknown provider hotspot module
|
||||
#pragma D attributes Private/Private/Unknown provider hotspot function
|
||||
#pragma D attributes Evolving/Evolving/Common provider hotspot name
|
||||
#pragma D attributes Evolving/Evolving/Common provider hotspot args
|
506
hotspot/src/os/bsd/dtrace/hotspot_jni.d
Normal file
506
hotspot/src/os/bsd/dtrace/hotspot_jni.d
Normal file
@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
provider hotspot_jni {
|
||||
probe AllocObject__entry(void*, void*);
|
||||
probe AllocObject__return(void*);
|
||||
probe AttachCurrentThreadAsDaemon__entry(void*, void**, void*);
|
||||
probe AttachCurrentThreadAsDaemon__return(uint32_t);
|
||||
probe AttachCurrentThread__entry(void*, void**, void*);
|
||||
probe AttachCurrentThread__return(uint32_t);
|
||||
probe CallBooleanMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallBooleanMethodA__return(uintptr_t);
|
||||
probe CallBooleanMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallBooleanMethod__return(uintptr_t);
|
||||
probe CallBooleanMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallBooleanMethodV__return(uintptr_t);
|
||||
probe CallByteMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallByteMethodA__return(char);
|
||||
probe CallByteMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallByteMethod__return(char);
|
||||
probe CallByteMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallByteMethodV__return(char);
|
||||
probe CallCharMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallCharMethodA__return(uint16_t);
|
||||
probe CallCharMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallCharMethod__return(uint16_t);
|
||||
probe CallCharMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallCharMethodV__return(uint16_t);
|
||||
probe CallDoubleMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallDoubleMethodA__return();
|
||||
probe CallDoubleMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallDoubleMethod__return();
|
||||
probe CallDoubleMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallDoubleMethodV__return();
|
||||
probe CallFloatMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallFloatMethodA__return();
|
||||
probe CallFloatMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallFloatMethod__return();
|
||||
probe CallFloatMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallFloatMethodV__return();
|
||||
probe CallIntMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallIntMethodA__return(uint32_t);
|
||||
probe CallIntMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallIntMethod__return(uint32_t);
|
||||
probe CallIntMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallIntMethodV__return(uint32_t);
|
||||
probe CallLongMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallLongMethodA__return(uintptr_t);
|
||||
probe CallLongMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallLongMethod__return(uintptr_t);
|
||||
probe CallLongMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallLongMethodV__return(uintptr_t);
|
||||
probe CallNonvirtualBooleanMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualBooleanMethodA__return(uintptr_t);
|
||||
probe CallNonvirtualBooleanMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualBooleanMethod__return(uintptr_t);
|
||||
probe CallNonvirtualBooleanMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualBooleanMethodV__return(uintptr_t);
|
||||
probe CallNonvirtualByteMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualByteMethodA__return(char);
|
||||
probe CallNonvirtualByteMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualByteMethod__return(char);
|
||||
probe CallNonvirtualByteMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualByteMethodV__return(char);
|
||||
probe CallNonvirtualCharMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualCharMethodA__return(uint16_t);
|
||||
probe CallNonvirtualCharMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualCharMethod__return(uint16_t);
|
||||
probe CallNonvirtualCharMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualCharMethodV__return(uint16_t);
|
||||
probe CallNonvirtualDoubleMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualDoubleMethodA__return();
|
||||
probe CallNonvirtualDoubleMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualDoubleMethod__return();
|
||||
probe CallNonvirtualDoubleMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualDoubleMethodV__return();
|
||||
probe CallNonvirtualFloatMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualFloatMethodA__return();
|
||||
probe CallNonvirtualFloatMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualFloatMethod__return();
|
||||
probe CallNonvirtualFloatMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualFloatMethodV__return();
|
||||
probe CallNonvirtualIntMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualIntMethodA__return(uint32_t);
|
||||
probe CallNonvirtualIntMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualIntMethod__return(uint32_t);
|
||||
probe CallNonvirtualIntMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualIntMethodV__return(uint32_t);
|
||||
probe CallNonvirtualLongMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualLongMethodA__return(uintptr_t);
|
||||
probe CallNonvirtualLongMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualLongMethod__return(uintptr_t);
|
||||
probe CallNonvirtualLongMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualLongMethodV__return(uintptr_t);
|
||||
probe CallNonvirtualObjectMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualObjectMethodA__return(void*);
|
||||
probe CallNonvirtualObjectMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualObjectMethod__return(void*);
|
||||
probe CallNonvirtualObjectMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualObjectMethodV__return(void*);
|
||||
probe CallNonvirtualShortMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualShortMethodA__return(uint16_t);
|
||||
probe CallNonvirtualShortMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualShortMethod__return(uint16_t);
|
||||
probe CallNonvirtualShortMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualShortMethodV__return(uint16_t);
|
||||
probe CallNonvirtualVoidMethodA__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualVoidMethodA__return();
|
||||
probe CallNonvirtualVoidMethod__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualVoidMethod__return();
|
||||
probe CallNonvirtualVoidMethodV__entry(void*, void*, void*, uintptr_t);
|
||||
probe CallNonvirtualVoidMethodV__return();
|
||||
probe CallObjectMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallObjectMethodA__return(void*);
|
||||
probe CallObjectMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallObjectMethod__return(void*);
|
||||
probe CallObjectMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallObjectMethodV__return(void*);
|
||||
probe CallShortMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallShortMethodA__return(uint16_t);
|
||||
probe CallShortMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallShortMethod__return(uint16_t);
|
||||
probe CallShortMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallShortMethodV__return(uint16_t);
|
||||
probe CallStaticBooleanMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticBooleanMethodA__return(uintptr_t);
|
||||
probe CallStaticBooleanMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticBooleanMethod__return(uintptr_t);
|
||||
probe CallStaticBooleanMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticBooleanMethodV__return(uintptr_t);
|
||||
probe CallStaticByteMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticByteMethodA__return(char);
|
||||
probe CallStaticByteMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticByteMethod__return(char);
|
||||
probe CallStaticByteMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticByteMethodV__return(char);
|
||||
probe CallStaticCharMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticCharMethodA__return(uint16_t);
|
||||
probe CallStaticCharMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticCharMethod__return(uint16_t);
|
||||
probe CallStaticCharMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticCharMethodV__return(uint16_t);
|
||||
probe CallStaticDoubleMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticDoubleMethodA__return();
|
||||
probe CallStaticDoubleMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticDoubleMethod__return();
|
||||
probe CallStaticDoubleMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticDoubleMethodV__return();
|
||||
probe CallStaticFloatMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticFloatMethodA__return();
|
||||
probe CallStaticFloatMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticFloatMethod__return();
|
||||
probe CallStaticFloatMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticFloatMethodV__return();
|
||||
probe CallStaticIntMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticIntMethodA__return(uint32_t);
|
||||
probe CallStaticIntMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticIntMethod__return(uint32_t);
|
||||
probe CallStaticIntMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticIntMethodV__return(uint32_t);
|
||||
probe CallStaticLongMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticLongMethodA__return(uintptr_t);
|
||||
probe CallStaticLongMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticLongMethod__return(uintptr_t);
|
||||
probe CallStaticLongMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticLongMethodV__return(uintptr_t);
|
||||
probe CallStaticObjectMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticObjectMethodA__return(void*);
|
||||
probe CallStaticObjectMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticObjectMethod__return(void*);
|
||||
probe CallStaticObjectMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticObjectMethodV__return(void*);
|
||||
probe CallStaticShortMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticShortMethodA__return(uint16_t);
|
||||
probe CallStaticShortMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticShortMethod__return(uint16_t);
|
||||
probe CallStaticShortMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticShortMethodV__return(uint16_t);
|
||||
probe CallStaticVoidMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticVoidMethodA__return();
|
||||
probe CallStaticVoidMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticVoidMethod__return();
|
||||
probe CallStaticVoidMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallStaticVoidMethodV__return();
|
||||
probe CallVoidMethodA__entry(void*, void*, uintptr_t);
|
||||
probe CallVoidMethodA__return();
|
||||
probe CallVoidMethod__entry(void*, void*, uintptr_t);
|
||||
probe CallVoidMethod__return();
|
||||
probe CallVoidMethodV__entry(void*, void*, uintptr_t);
|
||||
probe CallVoidMethodV__return();
|
||||
probe CreateJavaVM__entry(void**, void**, void*);
|
||||
probe CreateJavaVM__return(uint32_t);
|
||||
probe DefineClass__entry(void*, const char*, void*, char*, uintptr_t);
|
||||
probe DefineClass__return(void*);
|
||||
probe DeleteGlobalRef__entry(void*, void*);
|
||||
probe DeleteGlobalRef__return();
|
||||
probe DeleteLocalRef__entry(void*, void*);
|
||||
probe DeleteLocalRef__return();
|
||||
probe DeleteWeakGlobalRef__entry(void*, void*);
|
||||
probe DeleteWeakGlobalRef__return();
|
||||
probe DestroyJavaVM__entry(void*);
|
||||
probe DestroyJavaVM__return(uint32_t);
|
||||
probe DetachCurrentThread__entry(void*);
|
||||
probe DetachCurrentThread__return(uint32_t);
|
||||
probe EnsureLocalCapacity__entry(void*, uint32_t);
|
||||
probe EnsureLocalCapacity__return(uint32_t);
|
||||
probe ExceptionCheck__entry(void*);
|
||||
probe ExceptionCheck__return(uintptr_t);
|
||||
probe ExceptionClear__entry(void*);
|
||||
probe ExceptionClear__return();
|
||||
probe ExceptionDescribe__entry(void*);
|
||||
probe ExceptionDescribe__return();
|
||||
probe ExceptionOccurred__entry(void*);
|
||||
probe ExceptionOccurred__return(void*);
|
||||
probe FatalError__entry(void* env, const char*);
|
||||
probe FindClass__entry(void*, const char*);
|
||||
probe FindClass__return(void*);
|
||||
probe FromReflectedField__entry(void*, void*);
|
||||
probe FromReflectedField__return(uintptr_t);
|
||||
probe FromReflectedMethod__entry(void*, void*);
|
||||
probe FromReflectedMethod__return(uintptr_t);
|
||||
probe GetArrayLength__entry(void*, void*);
|
||||
probe GetArrayLength__return(uintptr_t);
|
||||
probe GetBooleanArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetBooleanArrayElements__return(uintptr_t*);
|
||||
probe GetBooleanArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, uintptr_t*);
|
||||
probe GetBooleanArrayRegion__return();
|
||||
probe GetBooleanField__entry(void*, void*, uintptr_t);
|
||||
probe GetBooleanField__return(uintptr_t);
|
||||
probe GetByteArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetByteArrayElements__return(char*);
|
||||
probe GetByteArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, char*);
|
||||
probe GetByteArrayRegion__return();
|
||||
probe GetByteField__entry(void*, void*, uintptr_t);
|
||||
probe GetByteField__return(char);
|
||||
probe GetCharArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetCharArrayElements__return(uint16_t*);
|
||||
probe GetCharArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, uint16_t*);
|
||||
probe GetCharArrayRegion__return();
|
||||
probe GetCharField__entry(void*, void*, uintptr_t);
|
||||
probe GetCharField__return(uint16_t);
|
||||
probe GetCreatedJavaVMs__entry(void**, uintptr_t, uintptr_t*);
|
||||
probe GetCreatedJavaVMs__return(uintptr_t);
|
||||
probe GetDefaultJavaVMInitArgs__entry(void*);
|
||||
probe GetDefaultJavaVMInitArgs__return(uint32_t);
|
||||
probe GetDirectBufferAddress__entry(void*, void*);
|
||||
probe GetDirectBufferAddress__return(void*);
|
||||
probe GetDirectBufferCapacity__entry(void*, void*);
|
||||
probe GetDirectBufferCapacity__return(uintptr_t);
|
||||
probe GetDoubleArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetDoubleArrayElements__return(double*);
|
||||
probe GetDoubleArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, double*);
|
||||
probe GetDoubleArrayRegion__return();
|
||||
probe GetDoubleField__entry(void*, void*, uintptr_t);
|
||||
probe GetDoubleField__return();
|
||||
probe GetEnv__entry(void*, void*, uint32_t);
|
||||
probe GetEnv__return(uint32_t);
|
||||
probe GetFieldID__entry(void*, void*, const char*, const char*);
|
||||
probe GetFieldID__return(uintptr_t);
|
||||
probe GetFloatArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetFloatArrayElements__return(float*);
|
||||
probe GetFloatArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, float*);
|
||||
probe GetFloatArrayRegion__return();
|
||||
probe GetFloatField__entry(void*, void*, uintptr_t);
|
||||
probe GetFloatField__return();
|
||||
probe GetIntArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetIntArrayElements__return(uint32_t*);
|
||||
probe GetIntArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, uint32_t*);
|
||||
probe GetIntArrayRegion__return();
|
||||
probe GetIntField__entry(void*, void*, uintptr_t);
|
||||
probe GetIntField__return(uint32_t);
|
||||
probe GetJavaVM__entry(void*, void**);
|
||||
probe GetJavaVM__return(uint32_t);
|
||||
probe GetLongArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetLongArrayElements__return(uintptr_t*);
|
||||
probe GetLongArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, uintptr_t*);
|
||||
probe GetLongArrayRegion__return();
|
||||
probe GetLongField__entry(void*, void*, uintptr_t);
|
||||
probe GetLongField__return(uintptr_t);
|
||||
probe GetMethodID__entry(void*, void*, const char*, const char*);
|
||||
probe GetMethodID__return(uintptr_t);
|
||||
probe GetObjectArrayElement__entry(void*, void*, uintptr_t);
|
||||
probe GetObjectArrayElement__return(void*);
|
||||
probe GetObjectClass__entry(void*, void*);
|
||||
probe GetObjectClass__return(void*);
|
||||
probe GetObjectField__entry(void*, void*, uintptr_t);
|
||||
probe GetObjectField__return(void*);
|
||||
probe GetObjectRefType__entry(void*, void*);
|
||||
probe GetObjectRefType__return(void*);
|
||||
probe GetPrimitiveArrayCritical__entry(void*, void*, uintptr_t*);
|
||||
probe GetPrimitiveArrayCritical__return(void*);
|
||||
probe GetShortArrayElements__entry(void*, void*, uintptr_t*);
|
||||
probe GetShortArrayElements__return(uint16_t*);
|
||||
probe GetShortArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, uint16_t*);
|
||||
probe GetShortArrayRegion__return();
|
||||
probe GetShortField__entry(void*, void*, uintptr_t);
|
||||
probe GetShortField__return(uint16_t);
|
||||
probe GetStaticBooleanField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticBooleanField__return(uintptr_t);
|
||||
probe GetStaticByteField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticByteField__return(char);
|
||||
probe GetStaticCharField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticCharField__return(uint16_t);
|
||||
probe GetStaticDoubleField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticDoubleField__return();
|
||||
probe GetStaticFieldID__entry(void*, void*, const char*, const char*);
|
||||
probe GetStaticFieldID__return(uintptr_t);
|
||||
probe GetStaticFloatField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticFloatField__return();
|
||||
probe GetStaticIntField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticIntField__return(uint32_t);
|
||||
probe GetStaticLongField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticLongField__return(uintptr_t);
|
||||
probe GetStaticMethodID__entry(void*, void*, const char*, const char*);
|
||||
probe GetStaticMethodID__return(uintptr_t);
|
||||
probe GetStaticObjectField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticObjectField__return(void*);
|
||||
probe GetStaticShortField__entry(void*, void*, uintptr_t);
|
||||
probe GetStaticShortField__return(uint16_t);
|
||||
probe GetStringChars__entry(void*, void*, uintptr_t*);
|
||||
probe GetStringChars__return(const uint16_t*);
|
||||
probe GetStringCritical__entry(void*, void*, uintptr_t*);
|
||||
probe GetStringCritical__return(const uint16_t*);
|
||||
probe GetStringLength__entry(void*, void*);
|
||||
probe GetStringLength__return(uintptr_t);
|
||||
probe GetStringRegion__entry(void*, void*, uintptr_t, uintptr_t, uint16_t*);
|
||||
probe GetStringRegion__return();
|
||||
probe GetStringUTFChars__entry(void*, void*, uintptr_t*);
|
||||
probe GetStringUTFChars__return(const char*);
|
||||
probe GetStringUTFLength__entry(void*, void*);
|
||||
probe GetStringUTFLength__return(uintptr_t);
|
||||
probe GetStringUTFRegion__entry(void*, void*, uintptr_t, uintptr_t, char*);
|
||||
probe GetStringUTFRegion__return();
|
||||
probe GetSuperclass__entry(void*, void*);
|
||||
probe GetSuperclass__return(void*);
|
||||
probe GetVersion__entry(void*);
|
||||
probe GetVersion__return(uint32_t);
|
||||
probe IsAssignableFrom__entry(void*, void*, void*);
|
||||
probe IsAssignableFrom__return(uintptr_t);
|
||||
probe IsInstanceOf__entry(void*, void*, void*);
|
||||
probe IsInstanceOf__return(uintptr_t);
|
||||
probe IsSameObject__entry(void*, void*, void*);
|
||||
probe IsSameObject__return(uintptr_t);
|
||||
probe MonitorEnter__entry(void*, void*);
|
||||
probe MonitorEnter__return(uint32_t);
|
||||
probe MonitorExit__entry(void*, void*);
|
||||
probe MonitorExit__return(uint32_t);
|
||||
probe NewBooleanArray__entry(void*, uintptr_t);
|
||||
probe NewBooleanArray__return(void*);
|
||||
probe NewByteArray__entry(void*, uintptr_t);
|
||||
probe NewByteArray__return(void*);
|
||||
probe NewCharArray__entry(void*, uintptr_t);
|
||||
probe NewCharArray__return(void*);
|
||||
probe NewDirectByteBuffer__entry(void*, void*, uintptr_t);
|
||||
probe NewDirectByteBuffer__return(void*);
|
||||
probe NewDoubleArray__entry(void*, uintptr_t);
|
||||
probe NewDoubleArray__return(void*);
|
||||
probe NewFloatArray__entry(void*, uintptr_t);
|
||||
probe NewFloatArray__return(void*);
|
||||
probe NewGlobalRef__entry(void*, void*);
|
||||
probe NewGlobalRef__return(void*);
|
||||
probe NewIntArray__entry(void*, uintptr_t);
|
||||
probe NewIntArray__return(void*);
|
||||
probe NewLocalRef__entry(void*, void*);
|
||||
probe NewLocalRef__return(void*);
|
||||
probe NewLongArray__entry(void*, uintptr_t);
|
||||
probe NewLongArray__return(void*);
|
||||
probe NewObjectA__entry(void*, void*, uintptr_t);
|
||||
probe NewObjectA__return(void*);
|
||||
probe NewObjectArray__entry(void*, uintptr_t, void*, void*);
|
||||
probe NewObjectArray__return(void*);
|
||||
probe NewObject__entry(void*, void*, uintptr_t);
|
||||
probe NewObject__return(void*);
|
||||
probe NewObjectV__entry(void*, void*, uintptr_t);
|
||||
probe NewObjectV__return(void*);
|
||||
probe NewShortArray__entry(void*, uintptr_t);
|
||||
probe NewShortArray__return(void*);
|
||||
probe NewString__entry(void*, const uint16_t*, uintptr_t);
|
||||
probe NewString__return(void*);
|
||||
probe NewStringUTF__entry(void*, const char*);
|
||||
probe NewStringUTF__return(void*);
|
||||
probe NewWeakGlobalRef__entry(void*, void*);
|
||||
probe NewWeakGlobalRef__return(void*);
|
||||
probe PopLocalFrame__entry(void*, void*);
|
||||
probe PopLocalFrame__return(void*);
|
||||
probe PushLocalFrame__entry(void*, uint32_t);
|
||||
probe PushLocalFrame__return(uint32_t);
|
||||
probe RegisterNatives__entry(void*, void*, const void*, uint32_t);
|
||||
probe RegisterNatives__return(uint32_t);
|
||||
probe ReleaseBooleanArrayElements__entry(void*, void*, uintptr_t*, uint32_t);
|
||||
probe ReleaseBooleanArrayElements__return();
|
||||
probe ReleaseByteArrayElements__entry(void*, void*, char*, uint32_t);
|
||||
probe ReleaseByteArrayElements__return();
|
||||
probe ReleaseCharArrayElements__entry(void*, void*, uint16_t*, uint32_t);
|
||||
probe ReleaseCharArrayElements__return();
|
||||
probe ReleaseDoubleArrayElements__entry(void*, void*, double*, uint32_t);
|
||||
probe ReleaseDoubleArrayElements__return();
|
||||
probe ReleaseFloatArrayElements__entry(void*, void*, float*, uint32_t);
|
||||
probe ReleaseFloatArrayElements__return();
|
||||
probe ReleaseIntArrayElements__entry(void*, void*, uint32_t*, uint32_t);
|
||||
probe ReleaseIntArrayElements__return();
|
||||
probe ReleaseLongArrayElements__entry(void*, void*, uintptr_t*, uint32_t);
|
||||
probe ReleaseLongArrayElements__return();
|
||||
probe ReleasePrimitiveArrayCritical__entry(void*, void*, void*, uint32_t);
|
||||
probe ReleasePrimitiveArrayCritical__return();
|
||||
probe ReleaseShortArrayElements__entry(void*, void*, uint16_t*, uint32_t);
|
||||
probe ReleaseShortArrayElements__return();
|
||||
probe ReleaseStringChars__entry(void*, void*, const uint16_t*);
|
||||
probe ReleaseStringChars__return();
|
||||
probe ReleaseStringCritical__entry(void*, void*, const uint16_t*);
|
||||
probe ReleaseStringCritical__return();
|
||||
probe ReleaseStringUTFChars__entry(void*, void*, const char*);
|
||||
probe ReleaseStringUTFChars__return();
|
||||
probe SetBooleanArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const uintptr_t*);
|
||||
probe SetBooleanArrayRegion__return();
|
||||
probe SetBooleanField__entry(void*, void*, uintptr_t, uintptr_t);
|
||||
probe SetBooleanField__return();
|
||||
probe SetByteArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const char*);
|
||||
probe SetByteArrayRegion__return();
|
||||
probe SetByteField__entry(void*, void*, uintptr_t, char);
|
||||
probe SetByteField__return();
|
||||
probe SetCharArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const uint16_t*);
|
||||
probe SetCharArrayRegion__return();
|
||||
probe SetCharField__entry(void*, void*, uintptr_t, uint16_t);
|
||||
probe SetCharField__return();
|
||||
probe SetDoubleArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const double*);
|
||||
probe SetDoubleArrayRegion__return();
|
||||
probe SetDoubleField__entry(void*, void*, uintptr_t);
|
||||
probe SetDoubleField__return();
|
||||
probe SetFloatArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const float*);
|
||||
probe SetFloatArrayRegion__return();
|
||||
probe SetFloatField__entry(void*, void*, uintptr_t);
|
||||
probe SetFloatField__return();
|
||||
probe SetIntArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const uint32_t*);
|
||||
probe SetIntArrayRegion__return();
|
||||
probe SetIntField__entry(void*, void*, uintptr_t, uint32_t);
|
||||
probe SetIntField__return();
|
||||
probe SetLongArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const uintptr_t*);
|
||||
probe SetLongArrayRegion__return();
|
||||
probe SetLongField__entry(void*, void*, uintptr_t, uintptr_t);
|
||||
probe SetLongField__return();
|
||||
probe SetObjectArrayElement__entry(void*, void*, uintptr_t, void*);
|
||||
probe SetObjectArrayElement__return();
|
||||
probe SetObjectField__entry(void*, void*, uintptr_t, void*);
|
||||
probe SetObjectField__return();
|
||||
probe SetShortArrayRegion__entry(void*, void*, uintptr_t, uintptr_t, const uint16_t*);
|
||||
probe SetShortArrayRegion__return();
|
||||
probe SetShortField__entry(void*, void*, uintptr_t, uint16_t);
|
||||
probe SetShortField__return();
|
||||
probe SetStaticBooleanField__entry(void*, void*, uintptr_t, uintptr_t);
|
||||
probe SetStaticBooleanField__return();
|
||||
probe SetStaticByteField__entry(void*, void*, uintptr_t, char);
|
||||
probe SetStaticByteField__return();
|
||||
probe SetStaticCharField__entry(void*, void*, uintptr_t, uint16_t);
|
||||
probe SetStaticCharField__return();
|
||||
probe SetStaticDoubleField__entry(void*, void*, uintptr_t);
|
||||
probe SetStaticDoubleField__return();
|
||||
probe SetStaticFloatField__entry(void*, void*, uintptr_t);
|
||||
probe SetStaticFloatField__return();
|
||||
probe SetStaticIntField__entry(void*, void*, uintptr_t, uint32_t);
|
||||
probe SetStaticIntField__return();
|
||||
probe SetStaticLongField__entry(void*, void*, uintptr_t, uintptr_t);
|
||||
probe SetStaticLongField__return();
|
||||
probe SetStaticObjectField__entry(void*, void*, uintptr_t, void*);
|
||||
probe SetStaticObjectField__return();
|
||||
probe SetStaticShortField__entry(void*, void*, uintptr_t, uint16_t);
|
||||
probe SetStaticShortField__return();
|
||||
probe Throw__entry(void*, void*);
|
||||
probe Throw__return(intptr_t);
|
||||
probe ThrowNew__entry(void*, void*, const char*);
|
||||
probe ThrowNew__return(intptr_t);
|
||||
probe ToReflectedField__entry(void*, void*, uintptr_t, uintptr_t);
|
||||
probe ToReflectedField__return(void*);
|
||||
probe ToReflectedMethod__entry(void*, void*, uintptr_t, uintptr_t);
|
||||
probe ToReflectedMethod__return(void*);
|
||||
probe UnregisterNatives__entry(void*, void*);
|
||||
probe UnregisterNatives__return(uint32_t);
|
||||
};
|
||||
|
||||
#pragma D attributes Standard/Standard/Common provider hotspot_jni provider
|
||||
#pragma D attributes Private/Private/Unknown provider hotspot_jni module
|
||||
#pragma D attributes Private/Private/Unknown provider hotspot_jni function
|
||||
#pragma D attributes Standard/Standard/Common provider hotspot_jni name
|
||||
#pragma D attributes Evolving/Evolving/Common provider hotspot_jni args
|
||||
|
40
hotspot/src/os/bsd/dtrace/hs_private.d
Normal file
40
hotspot/src/os/bsd/dtrace/hs_private.d
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
provider hs_private {
|
||||
probe hashtable__new_entry(void*, uint32_t, uintptr_t, void*);
|
||||
probe safepoint__begin();
|
||||
probe safepoint__end();
|
||||
probe cms__initmark__begin();
|
||||
probe cms__initmark__end();
|
||||
probe cms__remark__begin();
|
||||
probe cms__remark__end();
|
||||
};
|
||||
|
||||
#pragma D attributes Private/Private/Common provider hs_private provider
|
||||
#pragma D attributes Private/Private/Unknown provider hs_private module
|
||||
#pragma D attributes Private/Private/Unknown provider hs_private function
|
||||
#pragma D attributes Private/Private/Common provider hs_private name
|
||||
#pragma D attributes Private/Private/Common provider hs_private args
|
||||
|
447
hotspot/src/os/bsd/dtrace/jhelper.d
Normal file
447
hotspot/src/os/bsd/dtrace/jhelper.d
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This file is auto-generated */
|
||||
#include "JvmOffsetsIndex.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MARK_LINE this->line = __LINE__
|
||||
#else
|
||||
#define MARK_LINE
|
||||
#endif
|
||||
|
||||
#ifdef _LP64
|
||||
#define STACK_BIAS 0x7ff
|
||||
#define pointer uint64_t
|
||||
#else
|
||||
#define STACK_BIAS 0
|
||||
#define pointer uint32_t
|
||||
#endif
|
||||
|
||||
extern pointer __JvmOffsets;
|
||||
|
||||
extern pointer __1cJCodeCacheF_heap_;
|
||||
extern pointer __1cIUniverseP_methodKlassObj_;
|
||||
extern pointer __1cIUniverseO_collectedHeap_;
|
||||
extern pointer __1cIUniverseL_narrow_oop_;
|
||||
#ifdef _LP64
|
||||
extern pointer UseCompressedOops;
|
||||
#endif
|
||||
|
||||
extern pointer __1cHnmethodG__vtbl_;
|
||||
extern pointer __1cKBufferBlobG__vtbl_;
|
||||
|
||||
#define copyin_ptr(ADDR) *(pointer*) copyin((pointer) (ADDR), sizeof(pointer))
|
||||
#define copyin_uchar(ADDR) *(uchar_t*) copyin((pointer) (ADDR), sizeof(uchar_t))
|
||||
#define copyin_uint16(ADDR) *(uint16_t*) copyin((pointer) (ADDR), sizeof(uint16_t))
|
||||
#define copyin_uint32(ADDR) *(uint32_t*) copyin((pointer) (ADDR), sizeof(uint32_t))
|
||||
#define copyin_int32(ADDR) *(int32_t*) copyin((pointer) (ADDR), sizeof(int32_t))
|
||||
#define copyin_uint8(ADDR) *(uint8_t*) copyin((pointer) (ADDR), sizeof(uint8_t))
|
||||
|
||||
#define SAME(x) x
|
||||
#define copyin_offset(JVM_CONST) JVM_CONST = \
|
||||
copyin_int32(JvmOffsetsPtr + SAME(IDX_)JVM_CONST * sizeof(int32_t))
|
||||
|
||||
int init_done;
|
||||
|
||||
dtrace:helper:ustack:
|
||||
{
|
||||
MARK_LINE;
|
||||
this->done = 0;
|
||||
/*
|
||||
* TBD:
|
||||
* Here we initialize init_done, otherwise jhelper does not work.
|
||||
* Therefore, copyin_offset() statements work multiple times now.
|
||||
* There is a hope we could avoid it in the future, and so,
|
||||
* this initialization can be removed.
|
||||
*/
|
||||
init_done = 0;
|
||||
this->error = (char *) NULL;
|
||||
this->result = (char *) NULL;
|
||||
this->methodOop = 0;
|
||||
this->codecache = 0;
|
||||
this->klass = (pointer) NULL;
|
||||
this->vtbl = (pointer) NULL;
|
||||
this->suffix = '\0';
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
{
|
||||
MARK_LINE;
|
||||
/* Initialization of JvmOffsets constants */
|
||||
JvmOffsetsPtr = (pointer) &``__JvmOffsets;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!init_done && !this->done/
|
||||
{
|
||||
MARK_LINE;
|
||||
init_done = 1;
|
||||
|
||||
copyin_offset(COMPILER);
|
||||
copyin_offset(OFFSET_CollectedHeap_reserved);
|
||||
copyin_offset(OFFSET_MemRegion_start);
|
||||
copyin_offset(OFFSET_MemRegion_word_size);
|
||||
copyin_offset(SIZE_HeapWord);
|
||||
|
||||
copyin_offset(OFFSET_interpreter_frame_method);
|
||||
copyin_offset(OFFSET_Klass_name);
|
||||
copyin_offset(OFFSET_constantPoolOopDesc_pool_holder);
|
||||
|
||||
copyin_offset(OFFSET_HeapBlockHeader_used);
|
||||
copyin_offset(OFFSET_oopDesc_metadata);
|
||||
|
||||
copyin_offset(OFFSET_Symbol_length);
|
||||
copyin_offset(OFFSET_Symbol_body);
|
||||
|
||||
copyin_offset(OFFSET_methodOopDesc_constMethod);
|
||||
copyin_offset(OFFSET_methodOopDesc_constants);
|
||||
copyin_offset(OFFSET_constMethodOopDesc_name_index);
|
||||
copyin_offset(OFFSET_constMethodOopDesc_signature_index);
|
||||
|
||||
copyin_offset(OFFSET_CodeHeap_memory);
|
||||
copyin_offset(OFFSET_CodeHeap_segmap);
|
||||
copyin_offset(OFFSET_CodeHeap_log2_segment_size);
|
||||
|
||||
copyin_offset(OFFSET_VirtualSpace_low);
|
||||
copyin_offset(OFFSET_VirtualSpace_high);
|
||||
|
||||
copyin_offset(OFFSET_CodeBlob_name);
|
||||
|
||||
copyin_offset(OFFSET_nmethod_method);
|
||||
copyin_offset(SIZE_HeapBlockHeader);
|
||||
copyin_offset(SIZE_oopDesc);
|
||||
copyin_offset(SIZE_constantPoolOopDesc);
|
||||
|
||||
copyin_offset(OFFSET_NarrowOopStruct_base);
|
||||
copyin_offset(OFFSET_NarrowOopStruct_shift);
|
||||
|
||||
/*
|
||||
* The PC to translate is in arg0.
|
||||
*/
|
||||
this->pc = arg0;
|
||||
|
||||
/*
|
||||
* The methodOopPtr is in %l2 on SPARC. This can be found at
|
||||
* offset 8 from the frame pointer on 32-bit processes.
|
||||
*/
|
||||
#if defined(__sparc)
|
||||
this->methodOopPtr = copyin_ptr(arg1 + 2 * sizeof(pointer) + STACK_BIAS);
|
||||
#elif defined(__i386) || defined(__amd64)
|
||||
this->methodOopPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method);
|
||||
#else
|
||||
#error "Don't know architecture"
|
||||
#endif
|
||||
|
||||
this->Universe_methodKlassOop = copyin_ptr(&``__1cIUniverseP_methodKlassObj_);
|
||||
this->CodeCache_heap_address = copyin_ptr(&``__1cJCodeCacheF_heap_);
|
||||
|
||||
/* Reading volatile values */
|
||||
#ifdef _LP64
|
||||
this->Use_Compressed_Oops = copyin_uint8(&``UseCompressedOops);
|
||||
#else
|
||||
this->Use_Compressed_Oops = 0;
|
||||
#endif
|
||||
|
||||
this->Universe_narrow_oop_base = copyin_ptr(&``__1cIUniverseL_narrow_oop_ +
|
||||
OFFSET_NarrowOopStruct_base);
|
||||
this->Universe_narrow_oop_shift = copyin_int32(&``__1cIUniverseL_narrow_oop_ +
|
||||
OFFSET_NarrowOopStruct_shift);
|
||||
|
||||
this->CodeCache_low = copyin_ptr(this->CodeCache_heap_address +
|
||||
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low);
|
||||
|
||||
this->CodeCache_high = copyin_ptr(this->CodeCache_heap_address +
|
||||
OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high);
|
||||
|
||||
this->CodeCache_segmap_low = copyin_ptr(this->CodeCache_heap_address +
|
||||
OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low);
|
||||
|
||||
this->CodeCache_segmap_high = copyin_ptr(this->CodeCache_heap_address +
|
||||
OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_high);
|
||||
|
||||
this->CodeHeap_log2_segment_size = copyin_uint32(
|
||||
this->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size);
|
||||
|
||||
/*
|
||||
* Get Java heap bounds
|
||||
*/
|
||||
this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_);
|
||||
this->heap_start = copyin_ptr(this->Universe_collectedHeap +
|
||||
OFFSET_CollectedHeap_reserved +
|
||||
OFFSET_MemRegion_start);
|
||||
this->heap_size = SIZE_HeapWord *
|
||||
copyin_ptr(this->Universe_collectedHeap +
|
||||
OFFSET_CollectedHeap_reserved +
|
||||
OFFSET_MemRegion_word_size
|
||||
);
|
||||
this->heap_end = this->heap_start + this->heap_size;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done &&
|
||||
this->CodeCache_low <= this->pc && this->pc < this->CodeCache_high/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->codecache = 1;
|
||||
|
||||
/*
|
||||
* Find start.
|
||||
*/
|
||||
this->segment = (this->pc - this->CodeCache_low) >>
|
||||
this->CodeHeap_log2_segment_size;
|
||||
this->block = this->CodeCache_segmap_low;
|
||||
this->tag = copyin_uchar(this->block + this->segment);
|
||||
"second";
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && this->tag > 0/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->tag = copyin_uchar(this->block + this->segment);
|
||||
this->segment = this->segment - this->tag;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && this->tag > 0/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->tag = copyin_uchar(this->block + this->segment);
|
||||
this->segment = this->segment - this->tag;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && this->tag > 0/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->tag = copyin_uchar(this->block + this->segment);
|
||||
this->segment = this->segment - this->tag;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && this->tag > 0/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->tag = copyin_uchar(this->block + this->segment);
|
||||
this->segment = this->segment - this->tag;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && this->tag > 0/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->tag = copyin_uchar(this->block + this->segment);
|
||||
this->segment = this->segment - this->tag;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && this->tag > 0/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->error = "<couldn't find start>";
|
||||
this->done = 1;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->block = this->CodeCache_low +
|
||||
(this->segment << this->CodeHeap_log2_segment_size);
|
||||
this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used);
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache && !this->used/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->error = "<block not in use>";
|
||||
this->done = 1;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->start = this->block + SIZE_HeapBlockHeader;
|
||||
this->vtbl = copyin_ptr(this->start);
|
||||
|
||||
this->nmethod_vtbl = (pointer) &``__1cHnmethodG__vtbl_;
|
||||
this->BufferBlob_vtbl = (pointer) &``__1cKBufferBlobG__vtbl_;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->vtbl == this->nmethod_vtbl/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->methodOopPtr = copyin_ptr(this->start + OFFSET_nmethod_method);
|
||||
this->suffix = '*';
|
||||
this->methodOop = 1;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->vtbl == this->BufferBlob_vtbl/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->vtbl == this->BufferBlob_vtbl &&
|
||||
this->Use_Compressed_Oops == 0 &&
|
||||
this->methodOopPtr > this->heap_start && this->methodOopPtr < this->heap_end/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->klass = copyin_ptr(this->methodOopPtr + OFFSET_oopDesc_metadata);
|
||||
this->methodOop = this->klass == this->Universe_methodKlassOop;
|
||||
this->done = !this->methodOop;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->vtbl == this->BufferBlob_vtbl &&
|
||||
this->Use_Compressed_Oops != 0 &&
|
||||
this->methodOopPtr > this->heap_start && this->methodOopPtr < this->heap_end/
|
||||
{
|
||||
MARK_LINE;
|
||||
/*
|
||||
* Read compressed pointer and decode heap oop, same as oop.inline.hpp
|
||||
*/
|
||||
this->cklass = copyin_uint32(this->methodOopPtr + OFFSET_oopDesc_metadata);
|
||||
this->klass = (uint64_t)((uintptr_t)this->Universe_narrow_oop_base +
|
||||
((uintptr_t)this->cklass << this->Universe_narrow_oop_shift));
|
||||
this->methodOop = this->klass == this->Universe_methodKlassOop;
|
||||
this->done = !this->methodOop;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && !this->methodOop/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name);
|
||||
this->result = this->name != 0 ? copyinstr(this->name) : "<CodeBlob>";
|
||||
this->done = 1;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->methodOop/
|
||||
{
|
||||
MARK_LINE;
|
||||
this->constMethod = copyin_ptr(this->methodOopPtr +
|
||||
OFFSET_methodOopDesc_constMethod);
|
||||
|
||||
this->nameIndex = copyin_uint16(this->constMethod +
|
||||
OFFSET_constMethodOopDesc_name_index);
|
||||
|
||||
this->signatureIndex = copyin_uint16(this->constMethod +
|
||||
OFFSET_constMethodOopDesc_signature_index);
|
||||
|
||||
this->constantPool = copyin_ptr(this->methodOopPtr +
|
||||
OFFSET_methodOopDesc_constants);
|
||||
|
||||
this->nameSymbol = copyin_ptr(this->constantPool +
|
||||
this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
|
||||
|
||||
this->nameSymbolLength = copyin_uint16(this->nameSymbol +
|
||||
OFFSET_Symbol_length);
|
||||
|
||||
this->signatureSymbol = copyin_ptr(this->constantPool +
|
||||
this->signatureIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
|
||||
|
||||
this->signatureSymbolLength = copyin_uint16(this->signatureSymbol +
|
||||
OFFSET_Symbol_length);
|
||||
|
||||
this->klassPtr = copyin_ptr(this->constantPool +
|
||||
OFFSET_constantPoolOopDesc_pool_holder);
|
||||
|
||||
this->klassSymbol = copyin_ptr(this->klassPtr +
|
||||
OFFSET_Klass_name + SIZE_oopDesc);
|
||||
|
||||
this->klassSymbolLength = copyin_uint16(this->klassSymbol +
|
||||
OFFSET_Symbol_length);
|
||||
|
||||
/*
|
||||
* Enough for three strings, plus the '.', plus the trailing '\0'.
|
||||
*/
|
||||
this->result = (char *) alloca(this->klassSymbolLength +
|
||||
this->nameSymbolLength +
|
||||
this->signatureSymbolLength + 2 + 1);
|
||||
|
||||
copyinto(this->klassSymbol + OFFSET_Symbol_body,
|
||||
this->klassSymbolLength, this->result);
|
||||
|
||||
/*
|
||||
* Add the '.' between the class and the name.
|
||||
*/
|
||||
this->result[this->klassSymbolLength] = '.';
|
||||
|
||||
copyinto(this->nameSymbol + OFFSET_Symbol_body,
|
||||
this->nameSymbolLength,
|
||||
this->result + this->klassSymbolLength + 1);
|
||||
|
||||
copyinto(this->signatureSymbol + OFFSET_Symbol_body,
|
||||
this->signatureSymbolLength,
|
||||
this->result + this->klassSymbolLength +
|
||||
this->nameSymbolLength + 1);
|
||||
|
||||
/*
|
||||
* Now we need to add a trailing '\0' and possibly a tag character.
|
||||
*/
|
||||
this->result[this->klassSymbolLength + 1 +
|
||||
this->nameSymbolLength +
|
||||
this->signatureSymbolLength] = this->suffix;
|
||||
this->result[this->klassSymbolLength + 2 +
|
||||
this->nameSymbolLength +
|
||||
this->signatureSymbolLength] = '\0';
|
||||
|
||||
this->done = 1;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/this->done && this->error == (char *) NULL/
|
||||
{
|
||||
this->result;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/this->done && this->error != (char *) NULL/
|
||||
{
|
||||
this->error;
|
||||
}
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done && this->codecache/
|
||||
{
|
||||
this->done = 1;
|
||||
"error";
|
||||
}
|
||||
|
||||
|
||||
dtrace:helper:ustack:
|
||||
/!this->done/
|
||||
{
|
||||
NULL;
|
||||
}
|
565
hotspot/src/os/bsd/dtrace/jvm_dtrace.c
Normal file
565
hotspot/src/os/bsd/dtrace/jvm_dtrace.c
Normal file
@ -0,0 +1,565 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2010, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <door.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <thread.h>
|
||||
#include <unistd.h>
|
||||
#include "jvm_dtrace.h"
|
||||
|
||||
// NOTE: These constants are used in JVM code as well.
|
||||
// KEEP JVM CODE IN SYNC if you are going to change these...
|
||||
|
||||
#define DTRACE_ALLOC_PROBES 0x1
|
||||
#define DTRACE_METHOD_PROBES 0x2
|
||||
#define DTRACE_MONITOR_PROBES 0x4
|
||||
#define DTRACE_ALL_PROBES -1
|
||||
|
||||
// generic error messages
|
||||
#define JVM_ERR_OUT_OF_MEMORY "out of memory (native heap)"
|
||||
#define JVM_ERR_INVALID_PARAM "invalid input parameter(s)"
|
||||
#define JVM_ERR_NULL_PARAM "input paramater is NULL"
|
||||
|
||||
// error messages for attach
|
||||
#define JVM_ERR_CANT_OPEN_DOOR "cannot open door file"
|
||||
#define JVM_ERR_CANT_CREATE_ATTACH_FILE "cannot create attach file"
|
||||
#define JVM_ERR_DOOR_FILE_PERMISSION "door file is not secure"
|
||||
#define JVM_ERR_CANT_SIGNAL "cannot send SIGQUIT to target"
|
||||
|
||||
// error messages for enable probe
|
||||
#define JVM_ERR_DOOR_CMD_SEND "door command send failed"
|
||||
#define JVM_ERR_DOOR_CANT_READ_STATUS "cannot read door command status"
|
||||
#define JVM_ERR_DOOR_CMD_STATUS "door command error status"
|
||||
|
||||
// error message for detach
|
||||
#define JVM_ERR_CANT_CLOSE_DOOR "cannot close door file"
|
||||
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
struct _jvm_t {
|
||||
pid_t pid;
|
||||
int door_fd;
|
||||
};
|
||||
|
||||
static int libjvm_dtrace_debug;
|
||||
static void print_debug(const char* fmt,...) {
|
||||
if (libjvm_dtrace_debug) {
|
||||
va_list alist;
|
||||
va_start(alist, fmt);
|
||||
fputs("libjvm_dtrace DEBUG: ", stderr);
|
||||
vfprintf(stderr, fmt, alist);
|
||||
va_end(alist);
|
||||
}
|
||||
}
|
||||
|
||||
/* Key for thread local error message */
|
||||
static thread_key_t jvm_error_key;
|
||||
|
||||
/* init function for this library */
|
||||
static void init_jvm_dtrace() {
|
||||
/* check for env. var for debug mode */
|
||||
libjvm_dtrace_debug = getenv("LIBJVM_DTRACE_DEBUG") != NULL;
|
||||
/* create key for thread local error message */
|
||||
if (thr_keycreate(&jvm_error_key, NULL) != 0) {
|
||||
print_debug("can't create thread_key_t for jvm error key\n");
|
||||
// exit(1); ?
|
||||
}
|
||||
}
|
||||
|
||||
#pragma init(init_jvm_dtrace)
|
||||
|
||||
/* set thread local error message */
|
||||
static void set_jvm_error(const char* msg) {
|
||||
thr_setspecific(jvm_error_key, (void*)msg);
|
||||
}
|
||||
|
||||
/* clear thread local error message */
|
||||
static void clear_jvm_error() {
|
||||
thr_setspecific(jvm_error_key, NULL);
|
||||
}
|
||||
|
||||
/* file handling functions that can handle interrupt */
|
||||
|
||||
static int file_open(const char* path, int flag) {
|
||||
int ret;
|
||||
RESTARTABLE(open(path, flag), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int file_close(int fd) {
|
||||
int ret;
|
||||
RESTARTABLE(close(fd), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int file_read(int fd, char* buf, int len) {
|
||||
int ret;
|
||||
RESTARTABLE(read(fd, buf, len), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* send SIGQUIT signal to given process */
|
||||
static int send_sigquit(pid_t pid) {
|
||||
int ret;
|
||||
RESTARTABLE(kill(pid, SIGQUIT), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* called to check permissions on attach file */
|
||||
static int check_permission(const char* path) {
|
||||
struct stat64 sb;
|
||||
uid_t uid, gid;
|
||||
int res;
|
||||
|
||||
/*
|
||||
* Check that the path is owned by the effective uid/gid of this
|
||||
* process. Also check that group/other access is not allowed.
|
||||
*/
|
||||
uid = geteuid();
|
||||
gid = getegid();
|
||||
|
||||
res = stat64(path, &sb);
|
||||
if (res != 0) {
|
||||
print_debug("stat failed for %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sb.st_uid != uid) || (sb.st_gid != gid) ||
|
||||
((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0)) {
|
||||
print_debug("well-known file %s is not secure\n", path);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ATTACH_FILE_PATTERN "/tmp/.attach_pid%d"
|
||||
|
||||
/* fill-in the name of attach file name in given buffer */
|
||||
static void fill_attach_file_name(char* path, int len, pid_t pid) {
|
||||
memset(path, 0, len);
|
||||
sprintf(path, ATTACH_FILE_PATTERN, pid);
|
||||
}
|
||||
|
||||
#define DOOR_FILE_PATTERN "/tmp/.java_pid%d"
|
||||
|
||||
/* open door file for the given JVM */
|
||||
static int open_door(pid_t pid) {
|
||||
char path[PATH_MAX + 1];
|
||||
int fd;
|
||||
|
||||
sprintf(path, DOOR_FILE_PATTERN, pid);
|
||||
fd = file_open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
set_jvm_error(JVM_ERR_CANT_OPEN_DOOR);
|
||||
print_debug("cannot open door file %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
print_debug("opened door file %s\n", path);
|
||||
if (check_permission(path) != 0) {
|
||||
set_jvm_error(JVM_ERR_DOOR_FILE_PERMISSION);
|
||||
print_debug("check permission failed for %s\n", path);
|
||||
file_close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* create attach file for given process */
|
||||
static int create_attach_file(pid_t pid) {
|
||||
char path[PATH_MAX + 1];
|
||||
int fd;
|
||||
fill_attach_file_name(path, sizeof(path), pid);
|
||||
fd = file_open(path, O_CREAT | O_RDWR);
|
||||
if (fd < 0) {
|
||||
set_jvm_error(JVM_ERR_CANT_CREATE_ATTACH_FILE);
|
||||
print_debug("cannot create file %s\n", path);
|
||||
} else {
|
||||
print_debug("created attach file %s\n", path);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* delete attach file for given process */
|
||||
static void delete_attach_file(pid_t pid) {
|
||||
char path[PATH_MAX + 1];
|
||||
fill_attach_file_name(path, sizeof(path), pid);
|
||||
int res = unlink(path);
|
||||
if (res) {
|
||||
print_debug("cannot delete attach file %s\n", path);
|
||||
} else {
|
||||
print_debug("deleted attach file %s\n", path);
|
||||
}
|
||||
}
|
||||
|
||||
/* attach to given JVM */
|
||||
jvm_t* jvm_attach(pid_t pid) {
|
||||
jvm_t* jvm;
|
||||
int door_fd, attach_fd, i;
|
||||
|
||||
jvm = (jvm_t*) calloc(1, sizeof(jvm_t));
|
||||
if (jvm == NULL) {
|
||||
set_jvm_error(JVM_ERR_OUT_OF_MEMORY);
|
||||
print_debug("calloc failed in %s at %d\n", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
jvm->pid = pid;
|
||||
attach_fd = -1;
|
||||
|
||||
door_fd = open_door(pid);
|
||||
if (door_fd < 0) {
|
||||
print_debug("trying to create attach file\n");
|
||||
if ((attach_fd = create_attach_file(pid)) < 0) {
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* send QUIT signal to the target so that it will
|
||||
* check for the attach file.
|
||||
*/
|
||||
if (send_sigquit(pid) != 0) {
|
||||
set_jvm_error(JVM_ERR_CANT_SIGNAL);
|
||||
print_debug("sending SIGQUIT failed\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* give the target VM time to start the attach mechanism */
|
||||
do {
|
||||
int res;
|
||||
RESTARTABLE(poll(0, 0, 200), res);
|
||||
door_fd = open_door(pid);
|
||||
i++;
|
||||
} while (i <= 50 && door_fd == -1);
|
||||
if (door_fd < 0) {
|
||||
print_debug("Unable to open door to process %d\n", pid);
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
|
||||
quit:
|
||||
if (attach_fd >= 0) {
|
||||
file_close(attach_fd);
|
||||
delete_attach_file(jvm->pid);
|
||||
}
|
||||
if (door_fd >= 0) {
|
||||
jvm->door_fd = door_fd;
|
||||
clear_jvm_error();
|
||||
} else {
|
||||
free(jvm);
|
||||
jvm = NULL;
|
||||
}
|
||||
return jvm;
|
||||
}
|
||||
|
||||
/* return the last thread local error message */
|
||||
const char* jvm_get_last_error() {
|
||||
const char* res = NULL;
|
||||
thr_getspecific(jvm_error_key, (void**)&res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* detach the givenb JVM */
|
||||
int jvm_detach(jvm_t* jvm) {
|
||||
if (jvm) {
|
||||
int res;
|
||||
if (jvm->door_fd != -1) {
|
||||
if (file_close(jvm->door_fd) != 0) {
|
||||
set_jvm_error(JVM_ERR_CANT_CLOSE_DOOR);
|
||||
res = -1;
|
||||
} else {
|
||||
clear_jvm_error();
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
free(jvm);
|
||||
return res;
|
||||
} else {
|
||||
set_jvm_error(JVM_ERR_NULL_PARAM);
|
||||
print_debug("jvm_t* is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A simple table to translate some known errors into reasonable
|
||||
* error messages
|
||||
*/
|
||||
static struct {
|
||||
int err;
|
||||
const char* msg;
|
||||
} const error_messages[] = {
|
||||
{ 100, "Bad request" },
|
||||
{ 101, "Protocol mismatch" },
|
||||
{ 102, "Resource failure" },
|
||||
{ 103, "Internal error" },
|
||||
{ 104, "Permission denied" },
|
||||
};
|
||||
|
||||
/*
|
||||
* Lookup the given error code and return the appropriate
|
||||
* message. If not found return NULL.
|
||||
*/
|
||||
static const char* translate_error(int err) {
|
||||
int table_size = sizeof(error_messages) / sizeof(error_messages[0]);
|
||||
int i;
|
||||
|
||||
for (i=0; i<table_size; i++) {
|
||||
if (err == error_messages[i].err) {
|
||||
return error_messages[i].msg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Current protocol version
|
||||
*/
|
||||
static const char* PROTOCOL_VERSION = "1";
|
||||
|
||||
#define RES_BUF_SIZE 128
|
||||
|
||||
/*
|
||||
* Enqueue attach-on-demand command to the given JVM
|
||||
*/
|
||||
static
|
||||
int enqueue_command(jvm_t* jvm, const char* cstr, int arg_count, const char** args) {
|
||||
size_t size;
|
||||
door_arg_t door_args;
|
||||
char res_buffer[RES_BUF_SIZE];
|
||||
int rc, i;
|
||||
char* buf = NULL;
|
||||
int result = -1;
|
||||
|
||||
/*
|
||||
* First we get the command string and create the start of the
|
||||
* argument string to send to the target VM:
|
||||
* <ver>\0<cmd>\0
|
||||
*/
|
||||
if (cstr == NULL) {
|
||||
print_debug("command name is NULL\n");
|
||||
goto quit;
|
||||
}
|
||||
size = strlen(PROTOCOL_VERSION) + strlen(cstr) + 2;
|
||||
buf = (char*)malloc(size);
|
||||
if (buf != NULL) {
|
||||
char* pos = buf;
|
||||
strcpy(buf, PROTOCOL_VERSION);
|
||||
pos += strlen(PROTOCOL_VERSION)+1;
|
||||
strcpy(pos, cstr);
|
||||
} else {
|
||||
set_jvm_error(JVM_ERR_OUT_OF_MEMORY);
|
||||
print_debug("malloc failed at %d in %s\n", __LINE__, __FILE__);
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next we iterate over the arguments and extend the buffer
|
||||
* to include them.
|
||||
*/
|
||||
for (i=0; i<arg_count; i++) {
|
||||
cstr = args[i];
|
||||
if (cstr != NULL) {
|
||||
size_t len = strlen(cstr);
|
||||
char* newbuf = (char*)realloc(buf, size+len+1);
|
||||
if (newbuf == NULL) {
|
||||
set_jvm_error(JVM_ERR_OUT_OF_MEMORY);
|
||||
print_debug("realloc failed in %s at %d\n", __FILE__, __LINE__);
|
||||
goto quit;
|
||||
}
|
||||
buf = newbuf;
|
||||
strcpy(buf+size, cstr);
|
||||
size += len+1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The arguments to the door function are in 'buf' so we now
|
||||
* do the door call
|
||||
*/
|
||||
door_args.data_ptr = buf;
|
||||
door_args.data_size = size;
|
||||
door_args.desc_ptr = NULL;
|
||||
door_args.desc_num = 0;
|
||||
door_args.rbuf = (char*)&res_buffer;
|
||||
door_args.rsize = sizeof(res_buffer);
|
||||
|
||||
RESTARTABLE(door_call(jvm->door_fd, &door_args), rc);
|
||||
|
||||
/*
|
||||
* door_call failed
|
||||
*/
|
||||
if (rc == -1) {
|
||||
print_debug("door_call failed\n");
|
||||
} else {
|
||||
/*
|
||||
* door_call succeeded but the call didn't return the the expected jint.
|
||||
*/
|
||||
if (door_args.data_size < sizeof(int)) {
|
||||
print_debug("Enqueue error - reason unknown as result is truncated!");
|
||||
} else {
|
||||
int* res = (int*)(door_args.data_ptr);
|
||||
if (*res != 0) {
|
||||
const char* msg = translate_error(*res);
|
||||
if (msg == NULL) {
|
||||
print_debug("Unable to enqueue command to target VM: %d\n", *res);
|
||||
} else {
|
||||
print_debug("Unable to enqueue command to target VM: %s\n", msg);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The door call should return a file descriptor to one end of
|
||||
* a socket pair
|
||||
*/
|
||||
if ((door_args.desc_ptr != NULL) &&
|
||||
(door_args.desc_num == 1) &&
|
||||
(door_args.desc_ptr->d_attributes & DOOR_DESCRIPTOR)) {
|
||||
result = door_args.desc_ptr->d_data.d_desc.d_descriptor;
|
||||
} else {
|
||||
print_debug("Reply from enqueue missing descriptor!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quit:
|
||||
if (buf) free(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* read status code for a door command */
|
||||
static int read_status(int fd) {
|
||||
char ch, buf[16];
|
||||
int index = 0;
|
||||
|
||||
while (1) {
|
||||
if (file_read(fd, &ch, sizeof(ch)) != sizeof(ch)) {
|
||||
set_jvm_error(JVM_ERR_DOOR_CANT_READ_STATUS);
|
||||
print_debug("door cmd status: read status failed\n");
|
||||
return -1;
|
||||
}
|
||||
buf[index++] = ch;
|
||||
if (ch == '\n') {
|
||||
buf[index - 1] = '\0';
|
||||
return atoi(buf);
|
||||
}
|
||||
if (index == sizeof(buf)) {
|
||||
set_jvm_error(JVM_ERR_DOOR_CANT_READ_STATUS);
|
||||
print_debug("door cmd status: read status overflow\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char* ENABLE_DPROBES_CMD = "enabledprobes";
|
||||
|
||||
/* enable one or more DTrace probes for a given JVM */
|
||||
int jvm_enable_dtprobes(jvm_t* jvm, int num_probe_types, const char** probe_types) {
|
||||
int fd, status = 0;
|
||||
char ch;
|
||||
const char* args[1];
|
||||
char buf[16];
|
||||
int probe_type = 0, index;
|
||||
int count = 0;
|
||||
|
||||
if (jvm == NULL) {
|
||||
set_jvm_error(JVM_ERR_NULL_PARAM);
|
||||
print_debug("jvm_t* is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (num_probe_types == 0 || probe_types == NULL ||
|
||||
probe_types[0] == NULL) {
|
||||
set_jvm_error(JVM_ERR_INVALID_PARAM);
|
||||
print_debug("invalid probe type argument(s)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (index = 0; index < num_probe_types; index++) {
|
||||
const char* p = probe_types[index];
|
||||
if (strcmp(p, JVM_DTPROBE_OBJECT_ALLOC) == 0) {
|
||||
probe_type |= DTRACE_ALLOC_PROBES;
|
||||
count++;
|
||||
} else if (strcmp(p, JVM_DTPROBE_METHOD_ENTRY) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_METHOD_RETURN) == 0) {
|
||||
probe_type |= DTRACE_METHOD_PROBES;
|
||||
count++;
|
||||
} else if (strcmp(p, JVM_DTPROBE_MONITOR_ENTER) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_MONITOR_ENTERED) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_MONITOR_EXIT) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_MONITOR_WAIT) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_MONITOR_WAITED) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_MONITOR_NOTIFY) == 0 ||
|
||||
strcmp(p, JVM_DTPROBE_MONITOR_NOTIFYALL) == 0) {
|
||||
probe_type |= DTRACE_MONITOR_PROBES;
|
||||
count++;
|
||||
} else if (strcmp(p, JVM_DTPROBE_ALL) == 0) {
|
||||
probe_type |= DTRACE_ALL_PROBES;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
return count;
|
||||
}
|
||||
sprintf(buf, "%d", probe_type);
|
||||
args[0] = buf;
|
||||
|
||||
fd = enqueue_command(jvm, ENABLE_DPROBES_CMD, 1, args);
|
||||
if (fd < 0) {
|
||||
set_jvm_error(JVM_ERR_DOOR_CMD_SEND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = read_status(fd);
|
||||
// non-zero status is error
|
||||
if (status) {
|
||||
set_jvm_error(JVM_ERR_DOOR_CMD_STATUS);
|
||||
print_debug("%s command failed (status: %d) in target JVM\n",
|
||||
ENABLE_DPROBES_CMD, status);
|
||||
file_close(fd);
|
||||
return -1;
|
||||
}
|
||||
// read from stream until EOF
|
||||
while (file_read(fd, &ch, sizeof(ch)) == sizeof(ch)) {
|
||||
if (libjvm_dtrace_debug) {
|
||||
printf("%c", ch);
|
||||
}
|
||||
}
|
||||
|
||||
file_close(fd);
|
||||
clear_jvm_error();
|
||||
return count;
|
||||
}
|
86
hotspot/src/os/bsd/dtrace/jvm_dtrace.h
Normal file
86
hotspot/src/os/bsd/dtrace/jvm_dtrace.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2010, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _JVM_DTRACE_H_
|
||||
#define _JVM_DTRACE_H_
|
||||
|
||||
/*
|
||||
* Interface to dynamically turn on probes in Hotspot JVM. Currently,
|
||||
* this interface can be used to dynamically enable certain DTrace
|
||||
* probe points that are costly to have "always on".
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
struct _jvm_t;
|
||||
typedef struct _jvm_t jvm_t;
|
||||
|
||||
|
||||
/* Attach to the given JVM process. Returns NULL on failure.
|
||||
jvm_get_last_error() returns last error message. */
|
||||
jvm_t* jvm_attach(pid_t pid);
|
||||
|
||||
/* Returns the last error message from this library or NULL if none. */
|
||||
const char* jvm_get_last_error();
|
||||
|
||||
/* few well-known probe type constants for 'probe_types' param below */
|
||||
|
||||
#define JVM_DTPROBE_METHOD_ENTRY "method-entry"
|
||||
#define JVM_DTPROBE_METHOD_RETURN "method-return"
|
||||
#define JVM_DTPROBE_MONITOR_ENTER "monitor-contended-enter"
|
||||
#define JVM_DTPROBE_MONITOR_ENTERED "monitor-contended-entered"
|
||||
#define JVM_DTPROBE_MONITOR_EXIT "monitor-contended-exit"
|
||||
#define JVM_DTPROBE_MONITOR_WAIT "monitor-wait"
|
||||
#define JVM_DTPROBE_MONITOR_WAITED "monitor-waited"
|
||||
#define JVM_DTPROBE_MONITOR_NOTIFY "monitor-notify"
|
||||
#define JVM_DTPROBE_MONITOR_NOTIFYALL "monitor-notifyall"
|
||||
#define JVM_DTPROBE_OBJECT_ALLOC "object-alloc"
|
||||
#define JVM_DTPROBE_ALL "*"
|
||||
|
||||
/* Enable the specified DTrace probes of given probe types on
|
||||
* the specified JVM. Returns >= 0 on success, -1 on failure.
|
||||
* On success, this returns number of probe_types enabled.
|
||||
* On failure, jvm_get_last_error() returns the last error message.
|
||||
*/
|
||||
int jvm_enable_dtprobes(jvm_t* jvm, int num_probe_types, const char** probe_types);
|
||||
|
||||
/* Note: There is no jvm_disable_dtprobes function. Probes are automatically
|
||||
* disabled when there are no more clients requiring those probes.
|
||||
*/
|
||||
|
||||
/* Detach the given JVM. Returns 0 on success, -1 on failure.
|
||||
* jvm_get_last_error() returns the last error message.
|
||||
*/
|
||||
int jvm_detach(jvm_t* jvm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _JVM_DTRACE_H_ */
|
1548
hotspot/src/os/bsd/dtrace/libjvm_db.c
Normal file
1548
hotspot/src/os/bsd/dtrace/libjvm_db.c
Normal file
File diff suppressed because it is too large
Load Diff
68
hotspot/src/os/bsd/dtrace/libjvm_db.h
Normal file
68
hotspot/src/os/bsd/dtrace/libjvm_db.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_SOLARIS_DTRACE_LIBJVM_DB_H
|
||||
#define OS_SOLARIS_DTRACE_LIBJVM_DB_H
|
||||
|
||||
// not available on macosx #include <proc_service.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct jvm_agent jvm_agent_t;
|
||||
|
||||
#define JVM_DB_VERSION 1
|
||||
|
||||
jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers);
|
||||
|
||||
/*
|
||||
* Called from Jframe_iter() for each java frame. If it returns 0, then
|
||||
* Jframe_iter() proceeds to the next frame. Otherwise, the return value is
|
||||
* immediately returned to the caller of Jframe_iter().
|
||||
*
|
||||
* Parameters:
|
||||
* 'cld' is client supplied data (to maintain iterator state, if any).
|
||||
* 'name' is java method name.
|
||||
* 'bci' is byte code index. it will be -1 if not available.
|
||||
* 'line' is java source line number. it will be 0 if not available.
|
||||
* 'handle' is an abstract client handle, reserved for future expansions
|
||||
*/
|
||||
|
||||
typedef int java_stack_f(void *cld, const prgregset_t regs, const char* name, int bci, int line, void *handle);
|
||||
|
||||
/*
|
||||
* Iterates over the java frames at the current location. Returns -1 if no java
|
||||
* frames were found, or if there was some unrecoverable error. Otherwise,
|
||||
* returns the last value returned from 'func'.
|
||||
*/
|
||||
int Jframe_iter(jvm_agent_t *agent, prgregset_t gregs, java_stack_f *func, void* cld);
|
||||
|
||||
void Jagent_destroy(jvm_agent_t *J);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif // OS_SOLARIS_DTRACE_LIBJVM_DB_H
|
@ -33,6 +33,13 @@
|
||||
#include "runtime/signature.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
/*
|
||||
* JSDT java dtrace probes have never been implemented in macosx. It is unknown if the solaris implementation
|
||||
* is close or if significant implementation work is necessary. The future of the solaris implementation also
|
||||
* appears to be unclear since compiling code with JSDT probes produces the following warning:
|
||||
* "warning: ProviderFactory is internal proprietary API and may be removed in a future release"
|
||||
*/
|
||||
|
||||
int DTraceJSDT::pd_activate(
|
||||
void* baseAddress, jstring module,
|
||||
jint providers_count, JVM_DTraceProvider* providers) {
|
||||
|
@ -41,6 +41,21 @@
|
||||
* This file is currently collecting system-specific dregs for the
|
||||
* JNI conversion, which should be sorted out later.
|
||||
*/
|
||||
#ifdef __NetBSD__
|
||||
/*
|
||||
* Since we are compiling with c++, we need the following to make c macros
|
||||
* visible.
|
||||
*/
|
||||
# if !defined(__STDC_LIMIT_MACROS)
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
# endif
|
||||
# if !defined(__STDC_CONSTANT_MACROS)
|
||||
# define __STDC_CONSTANT_MACROS 1
|
||||
# endif
|
||||
# if !defined(__STDC_FORMAT_MACROS)
|
||||
# define __STDC_FORMAT_MACROS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <dirent.h> /* For DIR */
|
||||
#include <sys/param.h> /* For MAXPATHLEN */
|
||||
|
@ -136,8 +136,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach.h> // semaphore_* API
|
||||
#include <mach-o/dyld.h>
|
||||
# include <mach/mach.h> // semaphore_* API
|
||||
# include <mach-o/dyld.h>
|
||||
# include <sys/proc_info.h>
|
||||
# include <objc/objc-auto.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
@ -388,6 +390,20 @@ void os::Bsd::initialize_system_info() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
static const char *get_home() {
|
||||
const char *home_dir = ::getenv("HOME");
|
||||
if ((home_dir == NULL) || (*home_dir == '\0')) {
|
||||
struct passwd *passwd_info = getpwuid(geteuid());
|
||||
if (passwd_info != NULL) {
|
||||
home_dir = passwd_info->pw_dir;
|
||||
}
|
||||
}
|
||||
|
||||
return home_dir;
|
||||
}
|
||||
#endif
|
||||
|
||||
void os::init_system_properties_values() {
|
||||
// char arch[12];
|
||||
// sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
|
||||
@ -438,6 +454,15 @@ void os::init_system_properties_values() {
|
||||
#define ENDORSED_DIR "/lib/endorsed"
|
||||
#define REG_DIR "/usr/java/packages"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define SYS_EXTENSIONS_DIR "/Library/Java/Extensions"
|
||||
#define SYS_EXTENSIONS_DIRS SYS_EXTENSIONS_DIR ":/Network" SYS_EXTENSIONS_DIR ":/System" SYS_EXTENSIONS_DIR ":/usr/lib/java"
|
||||
const char *user_home_dir = get_home();
|
||||
// the null in SYS_EXTENSIONS_DIRS counts for the size of the colon after user_home_dir
|
||||
int system_ext_size = strlen(user_home_dir) + sizeof(SYS_EXTENSIONS_DIR) +
|
||||
sizeof(SYS_EXTENSIONS_DIRS);
|
||||
#endif
|
||||
|
||||
{
|
||||
/* sysclasspath, java_home, dll_dir */
|
||||
{
|
||||
@ -462,10 +487,12 @@ void os::init_system_properties_values() {
|
||||
if (pslash != NULL) {
|
||||
pslash = strrchr(buf, '/');
|
||||
if (pslash != NULL) {
|
||||
*pslash = '\0'; /* get rid of /<arch> */
|
||||
*pslash = '\0'; /* get rid of /<arch> (/lib on macosx) */
|
||||
#ifndef __APPLE__
|
||||
pslash = strrchr(buf, '/');
|
||||
if (pslash != NULL)
|
||||
*pslash = '\0'; /* get rid of /lib */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,9 +527,14 @@ void os::init_system_properties_values() {
|
||||
* nulls included by the sizeof operator (so actually we allocate
|
||||
* a byte more than necessary).
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
ld_library_path = (char *) malloc(system_ext_size);
|
||||
sprintf(ld_library_path, "%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS, user_home_dir);
|
||||
#else
|
||||
ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") +
|
||||
strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH));
|
||||
sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the user setting of LD_LIBRARY_PATH, and prepended it. It
|
||||
@ -510,6 +542,16 @@ void os::init_system_properties_values() {
|
||||
* addressed).
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
// Prepend the default path with the JAVA_LIBRARY_PATH so that the app launcher code can specify a directory inside an app wrapper
|
||||
char *l = getenv("JAVA_LIBRARY_PATH");
|
||||
if (l != NULL) {
|
||||
char *t = ld_library_path;
|
||||
/* That's +1 for the colon and +1 for the trailing '\0' */
|
||||
ld_library_path = (char *) malloc(strlen(l) + 1 + strlen(t) + 1);
|
||||
sprintf(ld_library_path, "%s:%s", l, t);
|
||||
free(t);
|
||||
}
|
||||
|
||||
char *v = getenv("DYLD_LIBRARY_PATH");
|
||||
#else
|
||||
char *v = getenv("LD_LIBRARY_PATH");
|
||||
@ -519,6 +561,7 @@ void os::init_system_properties_values() {
|
||||
/* That's +1 for the colon and +1 for the trailing '\0' */
|
||||
ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1);
|
||||
sprintf(ld_library_path, "%s:%s", v, t);
|
||||
free(t);
|
||||
}
|
||||
Arguments::set_library_path(ld_library_path);
|
||||
}
|
||||
@ -531,10 +574,18 @@ void os::init_system_properties_values() {
|
||||
* than necessary is allocated).
|
||||
*/
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
char *buf = malloc(strlen(Arguments::get_java_home()) +
|
||||
sizeof(EXTENSIONS_DIR) + system_ext_size);
|
||||
sprintf(buf, "%s" SYS_EXTENSIONS_DIR ":%s" EXTENSIONS_DIR ":"
|
||||
SYS_EXTENSIONS_DIRS, user_home_dir, Arguments::get_java_home());
|
||||
#else
|
||||
char *buf = malloc(strlen(Arguments::get_java_home()) +
|
||||
sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR));
|
||||
sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR,
|
||||
Arguments::get_java_home());
|
||||
#endif
|
||||
|
||||
Arguments::set_ext_dirs(buf);
|
||||
}
|
||||
|
||||
@ -547,6 +598,9 @@ void os::init_system_properties_values() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#undef SYS_EXTENSIONS_DIR
|
||||
#endif
|
||||
#undef malloc
|
||||
#undef getenv
|
||||
#undef EXTENSIONS_DIR
|
||||
@ -884,6 +938,16 @@ static bool _thread_safety_check(Thread* thread) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// library handle for calling objc_registerThreadWithCollector()
|
||||
// without static linking to the libobjc library
|
||||
#define OBJC_LIB "/usr/lib/libobjc.dylib"
|
||||
#define OBJC_GCREGISTER "objc_registerThreadWithCollector"
|
||||
typedef void (*objc_registerThreadWithCollector_t)();
|
||||
extern "C" objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction;
|
||||
objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL;
|
||||
#endif
|
||||
|
||||
// Thread start routine for all newly created threads
|
||||
static void *java_start(Thread *thread) {
|
||||
// Try to randomize the cache line index of hot stack frames.
|
||||
@ -929,6 +993,13 @@ static void *java_start(Thread *thread) {
|
||||
// initialize floating point control register
|
||||
os::Bsd::init_thread_fpu_state();
|
||||
|
||||
#ifdef __APPLE__
|
||||
// register thread with objc gc
|
||||
if (objc_registerThreadWithCollectorFunction != NULL) {
|
||||
objc_registerThreadWithCollectorFunction();
|
||||
}
|
||||
#endif
|
||||
|
||||
// handshaking with parent thread
|
||||
{
|
||||
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
|
||||
@ -1747,7 +1818,23 @@ const char* os::dll_file_extension() { return JNI_LIB_SUFFIX; }
|
||||
|
||||
// This must be hard coded because it's the system's temporary
|
||||
// directory not the java application's temp directory, ala java.io.tmpdir.
|
||||
#ifdef __APPLE__
|
||||
// macosx has a secure per-user temporary directory
|
||||
char temp_path_storage[PATH_MAX];
|
||||
const char* os::get_temp_directory() {
|
||||
static char *temp_path = NULL;
|
||||
if (temp_path == NULL) {
|
||||
int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, temp_path_storage, PATH_MAX);
|
||||
if (pathSize == 0 || pathSize > PATH_MAX) {
|
||||
strlcpy(temp_path_storage, "/tmp/", sizeof(temp_path_storage));
|
||||
}
|
||||
temp_path = temp_path_storage;
|
||||
}
|
||||
return temp_path;
|
||||
}
|
||||
#else /* __APPLE__ */
|
||||
const char* os::get_temp_directory() { return "/tmp"; }
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
static bool file_exists(const char* filename) {
|
||||
struct stat statbuf;
|
||||
@ -4531,6 +4618,14 @@ jint os::init_2(void)
|
||||
// initialize thread priority policy
|
||||
prio_init();
|
||||
|
||||
#ifdef __APPLE__
|
||||
// dynamically link to objective c gc registration
|
||||
void *handleLibObjc = dlopen(OBJC_LIB, RTLD_LAZY);
|
||||
if (handleLibObjc != NULL) {
|
||||
objc_registerThreadWithCollectorFunction = (objc_registerThreadWithCollector_t) dlsym(handleLibObjc, OBJC_GCREGISTER);
|
||||
}
|
||||
#endif
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
@ -4562,6 +4657,18 @@ int os::active_processor_count() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void os::set_native_thread_name(const char *name) {
|
||||
#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
|
||||
// This is only supported in Snow Leopard and beyond
|
||||
if (name != NULL) {
|
||||
// Add a "Java: " prefix to the name
|
||||
char buf[MAXTHREADNAMESIZE];
|
||||
snprintf(buf, sizeof(buf), "Java: %s", name);
|
||||
pthread_setname_np(buf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool os::distribute_processes(uint length, uint* distribution) {
|
||||
// Not yet implemented.
|
||||
return false;
|
||||
@ -5678,8 +5785,8 @@ bool os::is_headless_jre() {
|
||||
struct stat statbuf;
|
||||
char buf[MAXPATHLEN];
|
||||
char libmawtpath[MAXPATHLEN];
|
||||
const char *xawtstr = "/xawt/libmawt.so";
|
||||
const char *motifstr = "/motif21/libmawt.so";
|
||||
const char *xawtstr = "/xawt/libmawt" JNI_LIB_SUFFIX;
|
||||
const char *motifstr = "/motif21/libmawt" JNI_LIB_SUFFIX;
|
||||
char *p;
|
||||
|
||||
// Get path to libjvm.so
|
||||
|
@ -4357,6 +4357,11 @@ int os::active_processor_count() {
|
||||
return online_cpus;
|
||||
}
|
||||
|
||||
void os::set_native_thread_name(const char *name) {
|
||||
// Not yet implemented.
|
||||
return;
|
||||
}
|
||||
|
||||
bool os::distribute_processes(uint length, uint* distribution) {
|
||||
// Not yet implemented.
|
||||
return false;
|
||||
|
@ -669,6 +669,11 @@ static bool assign_distribution(processorid_t* id_array,
|
||||
return true;
|
||||
}
|
||||
|
||||
void os::set_native_thread_name(const char *name) {
|
||||
// Not yet implemented.
|
||||
return;
|
||||
}
|
||||
|
||||
bool os::distribute_processes(uint length, uint* distribution) {
|
||||
bool result = false;
|
||||
// Find the processor id's of all the available CPUs.
|
||||
|
@ -710,6 +710,11 @@ int os::active_processor_count() {
|
||||
}
|
||||
}
|
||||
|
||||
void os::set_native_thread_name(const char *name) {
|
||||
// Not yet implemented.
|
||||
return;
|
||||
}
|
||||
|
||||
bool os::distribute_processes(uint length, uint* distribution) {
|
||||
// Not yet implemented.
|
||||
return false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
@ -19,9 +19,9 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
# Darwin uses _ prefixed global symbols
|
||||
#define SYMBOL(s) _ ## s
|
||||
@ -31,37 +31,37 @@
|
||||
#define ELF_TYPE(name, description) .type name,description
|
||||
#endif
|
||||
|
||||
.globl SYMBOL(fixcw)
|
||||
|
||||
.globl SYMBOL(fixcw)
|
||||
|
||||
# NOTE WELL! The _Copy functions are called directly
|
||||
# from server-compiler-generated code via CallLeafNoFP,
|
||||
# which means that they *must* either not use floating
|
||||
# point or use it in the same manner as does the server
|
||||
# compiler.
|
||||
|
||||
# from server-compiler-generated code via CallLeafNoFP,
|
||||
# which means that they *must* either not use floating
|
||||
# point or use it in the same manner as does the server
|
||||
# compiler.
|
||||
|
||||
.globl SYMBOL(_Copy_conjoint_bytes)
|
||||
.globl SYMBOL(_Copy_arrayof_conjoint_bytes)
|
||||
.globl SYMBOL(_Copy_conjoint_jshorts_atomic)
|
||||
.globl SYMBOL(_Copy_arrayof_conjoint_jshorts)
|
||||
.globl SYMBOL(_Copy_arrayof_conjoint_jshorts)
|
||||
.globl SYMBOL(_Copy_conjoint_jints_atomic)
|
||||
.globl SYMBOL(_Copy_arrayof_conjoint_jints)
|
||||
.globl SYMBOL(_Copy_conjoint_jlongs_atomic)
|
||||
.globl SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts)
|
||||
.globl SYMBOL(_Copy_conjoint_jlongs_atomic)
|
||||
.globl SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts)
|
||||
|
||||
.globl SYMBOL(_Atomic_cmpxchg_long)
|
||||
.globl SYMBOL(_Atomic_move_long)
|
||||
|
||||
.text
|
||||
.text
|
||||
|
||||
# Support for void os::Solaris::init_thread_fpu_state() in os_solaris_i486.cpp
|
||||
# Set fpu to 53 bit precision. This happens too early to use a stub.
|
||||
# ported from solaris_x86_32.s
|
||||
.p2align 4,,15
|
||||
SYMBOL(fixcw):
|
||||
pushl $0x27f
|
||||
fldcw 0(%esp)
|
||||
popl %eax
|
||||
ret
|
||||
pushl $0x27f
|
||||
fldcw 0(%esp)
|
||||
popl %eax
|
||||
ret
|
||||
|
||||
.globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
|
||||
.globl SYMBOL(SafeFetchN)
|
||||
@ -69,7 +69,7 @@ SYMBOL(fixcw):
|
||||
## Instead, the signal handler would call a new SafeFetchTriage(FaultingEIP)
|
||||
## routine to vet the address. If the address is the faulting LD then
|
||||
## SafeFetchTriage() would return the resume-at EIP, otherwise null.
|
||||
ELF_TYPE(SafeFetch32,@function)
|
||||
ELF_TYPE(SafeFetch32,@function)
|
||||
.p2align 4,,15
|
||||
SYMBOL(SafeFetch32):
|
||||
SYMBOL(SafeFetchN):
|
||||
@ -82,7 +82,7 @@ SYMBOL(Fetch32Resume):
|
||||
|
||||
|
||||
.globl SYMBOL(SpinPause)
|
||||
ELF_TYPE(SpinPause,@function)
|
||||
ELF_TYPE(SpinPause,@function)
|
||||
.p2align 4,,15
|
||||
SYMBOL(SpinPause):
|
||||
rep
|
||||
@ -94,7 +94,7 @@ SYMBOL(SpinPause):
|
||||
# void* to,
|
||||
# size_t count)
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Copy_conjoint_bytes,@function)
|
||||
ELF_TYPE(_Copy_conjoint_bytes,@function)
|
||||
SYMBOL(_Copy_conjoint_bytes):
|
||||
pushl %esi
|
||||
movl 4+12(%esp),%ecx # count
|
||||
@ -188,7 +188,7 @@ cb_CopyLeft:
|
||||
addl $3,%esi
|
||||
6: movb (%esi),%dl
|
||||
movb %dl,(%edi,%esi,1)
|
||||
subl $1,%esi
|
||||
subl $1,%esi
|
||||
subl $1,%ecx
|
||||
jnz 6b
|
||||
7: cld
|
||||
@ -202,7 +202,7 @@ cb_CopyLeft:
|
||||
#
|
||||
# Same as _Copy_conjoint_bytes, except no source alignment check.
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function)
|
||||
ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function)
|
||||
SYMBOL(_Copy_arrayof_conjoint_bytes):
|
||||
pushl %esi
|
||||
movl 4+12(%esp),%ecx # count
|
||||
@ -213,7 +213,7 @@ SYMBOL(_Copy_arrayof_conjoint_bytes):
|
||||
leal -1(%esi,%ecx),%eax # from + count - 1
|
||||
jbe acb_CopyRight
|
||||
cmpl %eax,%edi
|
||||
jbe acb_CopyLeft
|
||||
jbe acb_CopyLeft
|
||||
# copy from low to high
|
||||
acb_CopyRight:
|
||||
cmpl $3,%ecx
|
||||
@ -262,7 +262,7 @@ acb_CopyLeft:
|
||||
jbe 2f # <= 32 dwords
|
||||
rep; smovl
|
||||
jmp 4f
|
||||
.=.+8
|
||||
.space 8
|
||||
2: subl %esi,%edi
|
||||
.p2align 4,,15
|
||||
3: movl (%esi),%edx
|
||||
@ -278,7 +278,7 @@ acb_CopyLeft:
|
||||
addl $3,%esi
|
||||
6: movb (%esi),%dl
|
||||
movb %dl,(%edi,%esi,1)
|
||||
subl $1,%esi
|
||||
subl $1,%esi
|
||||
subl $1,%ecx
|
||||
jnz 6b
|
||||
7: cld
|
||||
@ -290,7 +290,7 @@ acb_CopyLeft:
|
||||
# void* to,
|
||||
# size_t count)
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Copy_conjoint_jshorts_atomic,@function)
|
||||
ELF_TYPE(_Copy_conjoint_jshorts_atomic,@function)
|
||||
SYMBOL(_Copy_conjoint_jshorts_atomic):
|
||||
pushl %esi
|
||||
movl 4+12(%esp),%ecx # count
|
||||
@ -301,7 +301,7 @@ SYMBOL(_Copy_conjoint_jshorts_atomic):
|
||||
leal -2(%esi,%ecx,2),%eax # from + count*2 - 2
|
||||
jbe cs_CopyRight
|
||||
cmpl %eax,%edi
|
||||
jbe cs_CopyLeft
|
||||
jbe cs_CopyLeft
|
||||
# copy from low to high
|
||||
cs_CopyRight:
|
||||
# align source address at dword address boundary
|
||||
@ -322,7 +322,7 @@ cs_CopyRight:
|
||||
jbe 2f # <= 32 dwords
|
||||
# copy aligned dwords
|
||||
rep; smovl
|
||||
jmp 4f
|
||||
jmp 4f
|
||||
# copy aligned dwords
|
||||
2: subl %esi,%edi
|
||||
.p2align 4,,15
|
||||
@ -377,7 +377,7 @@ cs_CopyLeft:
|
||||
# void* to,
|
||||
# size_t count)
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Copy_arrayof_conjoint_jshorts,@function)
|
||||
ELF_TYPE(_Copy_arrayof_conjoint_jshorts,@function)
|
||||
SYMBOL(_Copy_arrayof_conjoint_jshorts):
|
||||
pushl %esi
|
||||
movl 4+12(%esp),%ecx # count
|
||||
@ -388,7 +388,7 @@ SYMBOL(_Copy_arrayof_conjoint_jshorts):
|
||||
leal -2(%esi,%ecx,2),%eax # from + count*2 - 2
|
||||
jbe acs_CopyRight
|
||||
cmpl %eax,%edi
|
||||
jbe acs_CopyLeft
|
||||
jbe acs_CopyLeft
|
||||
acs_CopyRight:
|
||||
movl %ecx,%eax # word count
|
||||
sarl %ecx # dword count
|
||||
@ -397,10 +397,10 @@ acs_CopyRight:
|
||||
jbe 2f # <= 32 dwords
|
||||
# copy aligned dwords
|
||||
rep; smovl
|
||||
jmp 4f
|
||||
jmp 4f
|
||||
# copy aligned dwords
|
||||
.=.+5
|
||||
2: subl %esi,%edi
|
||||
.space 5
|
||||
2: subl %esi,%edi
|
||||
.p2align 4,,15
|
||||
3: movl (%esi),%edx
|
||||
movl %edx,(%edi,%esi,1)
|
||||
@ -454,8 +454,8 @@ acs_CopyLeft:
|
||||
# Equivalent to
|
||||
# arrayof_conjoint_jints
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Copy_conjoint_jints_atomic,@function)
|
||||
ELF_TYPE(_Copy_arrayof_conjoint_jints,@function)
|
||||
ELF_TYPE(_Copy_conjoint_jints_atomic,@function)
|
||||
ELF_TYPE(_Copy_arrayof_conjoint_jints,@function)
|
||||
SYMBOL(_Copy_conjoint_jints_atomic):
|
||||
SYMBOL(_Copy_arrayof_conjoint_jints):
|
||||
pushl %esi
|
||||
@ -467,7 +467,7 @@ SYMBOL(_Copy_arrayof_conjoint_jints):
|
||||
leal -4(%esi,%ecx,4),%eax # from + count*4 - 4
|
||||
jbe ci_CopyRight
|
||||
cmpl %eax,%edi
|
||||
jbe ci_CopyLeft
|
||||
jbe ci_CopyLeft
|
||||
ci_CopyRight:
|
||||
cmpl $32,%ecx
|
||||
jbe 2f # <= 32 dwords
|
||||
@ -475,7 +475,7 @@ ci_CopyRight:
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
.=.+10
|
||||
.space 10
|
||||
2: subl %esi,%edi
|
||||
jmp 4f
|
||||
.p2align 4,,15
|
||||
@ -510,7 +510,7 @@ ci_CopyLeft:
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
|
||||
# Support for void Copy::conjoint_jlongs_atomic(jlong* from,
|
||||
# jlong* to,
|
||||
# size_t count)
|
||||
@ -529,7 +529,7 @@ ci_CopyLeft:
|
||||
# }
|
||||
# }
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Copy_conjoint_jlongs_atomic,@function)
|
||||
ELF_TYPE(_Copy_conjoint_jlongs_atomic,@function)
|
||||
SYMBOL(_Copy_conjoint_jlongs_atomic):
|
||||
movl 4+8(%esp),%ecx # count
|
||||
movl 4+0(%esp),%eax # from
|
||||
@ -558,7 +558,7 @@ cla_CopyLeft:
|
||||
# void* to,
|
||||
# size_t count)
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_mmx_Copy_arrayof_conjoint_jshorts,@function)
|
||||
ELF_TYPE(_mmx_Copy_arrayof_conjoint_jshorts,@function)
|
||||
SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts):
|
||||
pushl %esi
|
||||
movl 4+12(%esp),%ecx
|
||||
@ -576,7 +576,7 @@ mmx_acs_CopyRight:
|
||||
je 5f
|
||||
cmpl $33,%ecx
|
||||
jae 3f
|
||||
1: subl %esi,%edi
|
||||
1: subl %esi,%edi
|
||||
.p2align 4,,15
|
||||
2: movl (%esi),%edx
|
||||
movl %edx,(%edi,%esi,1)
|
||||
@ -584,7 +584,7 @@ mmx_acs_CopyRight:
|
||||
subl $1,%ecx
|
||||
jnz 2b
|
||||
addl %esi,%edi
|
||||
jmp 5f
|
||||
jmp 5f
|
||||
3: smovl # align to 8 bytes, we know we are 4 byte aligned to start
|
||||
subl $1,%ecx
|
||||
4: .p2align 4,,15
|
||||
@ -610,13 +610,13 @@ mmx_acs_CopyRight:
|
||||
cmpl $16,%ecx
|
||||
jge 4b
|
||||
emms
|
||||
testl %ecx,%ecx
|
||||
ja 1b
|
||||
testl %ecx,%ecx
|
||||
ja 1b
|
||||
5: andl $1,%eax
|
||||
je 7f
|
||||
6: movw (%esi),%dx
|
||||
movw %dx,(%edi)
|
||||
7: popl %edi
|
||||
7: popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
mmx_acs_CopyLeft:
|
||||
@ -657,7 +657,7 @@ mmx_acs_CopyLeft:
|
||||
# bool is_MP)
|
||||
#
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Atomic_cmpxchg_long,@function)
|
||||
ELF_TYPE(_Atomic_cmpxchg_long,@function)
|
||||
SYMBOL(_Atomic_cmpxchg_long):
|
||||
# 8(%esp) : return PC
|
||||
pushl %ebx # 4(%esp) : old %ebx
|
||||
@ -679,7 +679,7 @@ SYMBOL(_Atomic_cmpxchg_long):
|
||||
# Support for jlong Atomic::load and Atomic::store.
|
||||
# void _Atomic_move_long(volatile jlong* src, volatile jlong* dst)
|
||||
.p2align 4,,15
|
||||
ELF_TYPE(_Atomic_move_long,@function)
|
||||
ELF_TYPE(_Atomic_move_long,@function)
|
||||
SYMBOL(_Atomic_move_long):
|
||||
movl 4(%esp), %eax # src
|
||||
fildll (%eax)
|
||||
|
@ -275,7 +275,11 @@
|
||||
#endif
|
||||
|
||||
address os::current_stack_pointer() {
|
||||
#ifdef SPARC_WORKS
|
||||
#if defined(__clang__) || defined(__llvm__)
|
||||
register void *esp;
|
||||
__asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
|
||||
return (address) esp;
|
||||
#elif defined(SPARC_WORKS)
|
||||
register void *esp;
|
||||
__asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
|
||||
return (address) ((char*)esp + sizeof(long)*2);
|
||||
@ -358,7 +362,7 @@ frame os::get_sender_for_C_frame(frame* fr) {
|
||||
}
|
||||
|
||||
intptr_t* _get_previous_fp() {
|
||||
#ifdef SPARC_WORKS
|
||||
#if defined(SPARC_WORKS) || defined(__clang__)
|
||||
register intptr_t **ebp;
|
||||
__asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
|
||||
#else
|
||||
|
@ -29,7 +29,7 @@
|
||||
// ordering to native byte ordering and vice versa.
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <libkern/OSByteOrder.h>
|
||||
# include <libkern/OSByteOrder.h>
|
||||
#else
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
@ -169,7 +169,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
|
||||
if (info != NULL && thread != NULL) {
|
||||
// Handle ALL stack overflow variations here
|
||||
if (sig == SIGSEGV) {
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
@ -228,7 +228,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
// of write protecting the memory serialization page. It write
|
||||
// enables the page immediately after protecting it so we can
|
||||
// just return to retry the write.
|
||||
if (sig == SIGSEGV &&
|
||||
if ((sig == SIGSEGV || sig == SIGBUS) &&
|
||||
os::is_memory_serialize_page(thread, (address) info->si_addr)) {
|
||||
// Block current thread until permission is restored.
|
||||
os::block_on_serialize_page_trap();
|
||||
@ -260,10 +260,11 @@ JVM_handle_bsd_signal(int sig,
|
||||
}
|
||||
#endif // !PRODUCT
|
||||
|
||||
const char *fmt = "caught unhandled signal %d";
|
||||
char buf[64];
|
||||
const char *fmt =
|
||||
"caught unhandled signal " INT32_FORMAT " at address " PTR_FORMAT;
|
||||
char buf[128];
|
||||
|
||||
sprintf(buf, fmt, sig);
|
||||
sprintf(buf, fmt, sig, info->si_addr);
|
||||
fatal(buf);
|
||||
}
|
||||
|
||||
@ -338,7 +339,8 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
int rslt = pthread_stackseg_np(pthread_self(), &ss);
|
||||
|
||||
if (rslt != 0)
|
||||
fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt));
|
||||
fatal(err_msg("pthread_stackseg_np failed with err = " INT32_FORMAT,
|
||||
rslt));
|
||||
|
||||
stack_top = (address) ss.ss_sp;
|
||||
stack_bytes = ss.ss_size;
|
||||
@ -350,12 +352,13 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
|
||||
// JVM needs to know exact stack location, abort if it fails
|
||||
if (rslt != 0)
|
||||
fatal(err_msg("pthread_attr_init failed with err = %d", rslt));
|
||||
fatal(err_msg("pthread_attr_init failed with err = " INT32_FORMAT, rslt));
|
||||
|
||||
rslt = pthread_attr_get_np(pthread_self(), &attr);
|
||||
|
||||
if (rslt != 0)
|
||||
fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt));
|
||||
fatal(err_msg("pthread_attr_get_np failed with err = " INT32_FORMAT,
|
||||
rslt));
|
||||
|
||||
if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 ||
|
||||
pthread_attr_getstacksize(&attr, &stack_bytes) != 0) {
|
||||
@ -373,13 +376,15 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
vm_exit_out_of_memory(0, "pthread_getattr_np");
|
||||
}
|
||||
else {
|
||||
fatal(err_msg("pthread_getattr_np failed with errno = %d", res));
|
||||
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 = %d", res));
|
||||
fatal(err_msg("pthread_attr_getstack failed with errno = " INT32_FORMAT,
|
||||
res));
|
||||
}
|
||||
stack_top = stack_bottom + stack_bytes;
|
||||
|
||||
@ -391,7 +396,8 @@ static void current_stack_region(address *bottom, size_t *size) {
|
||||
size_t guard_bytes;
|
||||
res = pthread_attr_getguardsize(&attr, &guard_bytes);
|
||||
if (res != 0) {
|
||||
fatal(err_msg("pthread_attr_getguardsize failed with errno = %d", res));
|
||||
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");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2011, 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
|
||||
@ -85,13 +85,35 @@ static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
|
||||
}
|
||||
|
||||
static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
|
||||
// FIXME
|
||||
(void)memmove(to, from, count << LogBytesPerShort);
|
||||
if (from > to) {
|
||||
while (count-- > 0) {
|
||||
// Copy forwards
|
||||
*to++ = *from++;
|
||||
}
|
||||
} else {
|
||||
from += count - 1;
|
||||
to += count - 1;
|
||||
while (count-- > 0) {
|
||||
// Copy backwards
|
||||
*to-- = *from--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
|
||||
// FIXME
|
||||
(void)memmove(to, from, count << LogBytesPerInt);
|
||||
if (from > to) {
|
||||
while (count-- > 0) {
|
||||
// Copy forwards
|
||||
*to++ = *from++;
|
||||
}
|
||||
} else {
|
||||
from += count - 1;
|
||||
to += count - 1;
|
||||
while (count-- > 0) {
|
||||
// Copy backwards
|
||||
*to-- = *from--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
|
||||
|
@ -1165,11 +1165,11 @@ void GraphBuilder::_goto(int from_bci, int to_bci) {
|
||||
Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
|
||||
if (is_profiling()) {
|
||||
compilation()->set_would_profile(true);
|
||||
}
|
||||
if (profile_branches()) {
|
||||
x->set_profiled_method(method());
|
||||
x->set_profiled_bci(bci());
|
||||
x->set_should_profile(true);
|
||||
if (profile_branches()) {
|
||||
x->set_profiled_method(method());
|
||||
x->set_should_profile(true);
|
||||
}
|
||||
}
|
||||
append(x);
|
||||
}
|
||||
@ -1203,9 +1203,9 @@ void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* sta
|
||||
Goto *goto_node = i->as_Goto();
|
||||
if (goto_node != NULL) {
|
||||
compilation()->set_would_profile(true);
|
||||
goto_node->set_profiled_bci(bci());
|
||||
if (profile_branches()) {
|
||||
goto_node->set_profiled_method(method());
|
||||
goto_node->set_profiled_bci(bci());
|
||||
goto_node->set_should_profile(true);
|
||||
// Find out which successor is used.
|
||||
if (goto_node->default_sux() == tsux) {
|
||||
|
@ -2493,7 +2493,7 @@ void LIRGenerator::do_Goto(Goto* x) {
|
||||
|
||||
// increment backedge counter if needed
|
||||
CodeEmitInfo* info = state_for(x, state);
|
||||
increment_backedge_counter(info, info->stack()->bci());
|
||||
increment_backedge_counter(info, x->profiled_bci());
|
||||
CodeEmitInfo* safepoint_info = state_for(x, state);
|
||||
__ safepoint(safepoint_poll_register(), safepoint_info);
|
||||
}
|
||||
|
@ -2619,6 +2619,24 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeV
|
||||
|
||||
Location::Type loc_type = float_saved_as_double ? Location::float_in_dbl : Location::normal;
|
||||
VMReg rname = frame_map()->fpu_regname(opr->fpu_regnr());
|
||||
#ifndef __SOFTFP__
|
||||
#ifndef VM_LITTLE_ENDIAN
|
||||
if (! float_saved_as_double) {
|
||||
// On big endian system, we may have an issue if float registers use only
|
||||
// the low half of the (same) double registers.
|
||||
// Both the float and the double could have the same regnr but would correspond
|
||||
// to two different addresses once saved.
|
||||
|
||||
// get next safely (no assertion checks)
|
||||
VMReg next = VMRegImpl::as_VMReg(1+rname->value());
|
||||
if (next->is_reg() &&
|
||||
(next->as_FloatRegister() == rname->as_FloatRegister())) {
|
||||
// the back-end does use the same numbering for the double and the float
|
||||
rname = next; // VMReg for the low bits, e.g. the real VMReg for the float
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
LocationValue* sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
|
||||
|
||||
scope_values->append(sv);
|
||||
|
@ -473,6 +473,7 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
|
||||
}
|
||||
|
||||
if (require_local) return NULL;
|
||||
|
||||
// Not yet loaded into the VM, or not governed by loader constraints.
|
||||
// Make a CI representative for it.
|
||||
return get_unloaded_klass(accessing_klass, name);
|
||||
@ -498,7 +499,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
|
||||
bool& is_accessible,
|
||||
ciInstanceKlass* accessor) {
|
||||
EXCEPTION_CONTEXT;
|
||||
KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
|
||||
KlassHandle klass(THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
|
||||
Symbol* klass_name = NULL;
|
||||
if (klass.is_null()) {
|
||||
// The klass has not been inserted into the constant pool.
|
||||
@ -785,17 +786,17 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
|
||||
// Either the declared holder was not loaded, or the method could
|
||||
// not be found. Create a dummy ciMethod to represent the failed
|
||||
// lookup.
|
||||
|
||||
return get_unloaded_method(declared_holder,
|
||||
get_symbol(name_sym),
|
||||
get_symbol(sig_sym));
|
||||
ciSymbol* name = get_symbol(name_sym);
|
||||
ciSymbol* signature = get_symbol(sig_sym);
|
||||
return get_unloaded_method(declared_holder, name, signature, accessor);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciEnv::get_fake_invokedynamic_method_impl
|
||||
ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
|
||||
int index, Bytecodes::Code bc) {
|
||||
int index, Bytecodes::Code bc,
|
||||
ciInstanceKlass* accessor) {
|
||||
// Compare the following logic with InterpreterRuntime::resolve_invokedynamic.
|
||||
assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
|
||||
|
||||
@ -807,9 +808,10 @@ ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
|
||||
// Call site might not be resolved yet. We could create a real invoker method from the
|
||||
// compiler, but it is simpler to stop the code path here with an unlinked method.
|
||||
if (!is_resolved) {
|
||||
ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
|
||||
ciSymbol* sig_sym = get_symbol(cpool->signature_ref_at(index));
|
||||
return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym);
|
||||
ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
|
||||
ciSymbol* name = ciSymbol::invokeExact_name();
|
||||
ciSymbol* signature = get_symbol(cpool->signature_ref_at(index));
|
||||
return get_unloaded_method(holder, name, signature, accessor);
|
||||
}
|
||||
|
||||
// Get the invoker methodOop from the constant pool.
|
||||
@ -850,9 +852,9 @@ ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,
|
||||
int index, Bytecodes::Code bc,
|
||||
ciInstanceKlass* accessor) {
|
||||
if (bc == Bytecodes::_invokedynamic) {
|
||||
GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc);)
|
||||
GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc, accessor);)
|
||||
} else {
|
||||
GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
|
||||
GUARDED_VM_ENTRY(return get_method_by_index_impl( cpool, index, bc, accessor);)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,8 @@ private:
|
||||
int method_index, Bytecodes::Code bc,
|
||||
ciInstanceKlass* loading_klass);
|
||||
ciMethod* get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
|
||||
int index, Bytecodes::Code bc);
|
||||
int index, Bytecodes::Code bc,
|
||||
ciInstanceKlass* accessor);
|
||||
|
||||
// Helper methods
|
||||
bool check_klass_accessibility(ciKlass* accessing_klass,
|
||||
@ -192,13 +193,14 @@ private:
|
||||
// the result.
|
||||
ciMethod* get_unloaded_method(ciInstanceKlass* holder,
|
||||
ciSymbol* name,
|
||||
ciSymbol* signature) {
|
||||
return _factory->get_unloaded_method(holder, name, signature);
|
||||
ciSymbol* signature,
|
||||
ciInstanceKlass* accessor) {
|
||||
return _factory->get_unloaded_method(holder, name, signature, accessor);
|
||||
}
|
||||
|
||||
// Get a ciKlass representing an unloaded klass.
|
||||
// Ensures uniqueness of the result.
|
||||
ciKlass* get_unloaded_klass(ciKlass* accessing_klass,
|
||||
ciKlass* get_unloaded_klass(ciKlass* accessing_klass,
|
||||
ciSymbol* name) {
|
||||
return _factory->get_unloaded_klass(accessing_klass, name, true);
|
||||
}
|
||||
@ -224,7 +226,7 @@ private:
|
||||
|
||||
// See if we already have an unloaded klass for the given name
|
||||
// or return NULL if not.
|
||||
ciKlass *check_get_unloaded_klass(ciKlass* accessing_klass, ciSymbol* name) {
|
||||
ciKlass *check_get_unloaded_klass(ciKlass* accessing_klass, ciSymbol* name) {
|
||||
return _factory->get_unloaded_klass(accessing_klass, name, false);
|
||||
}
|
||||
|
||||
|
@ -148,21 +148,27 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
|
||||
//
|
||||
// Unloaded method.
|
||||
ciMethod::ciMethod(ciInstanceKlass* holder,
|
||||
ciSymbol* name,
|
||||
ciSymbol* signature) : ciObject(ciMethodKlass::make()) {
|
||||
// These fields are always filled in.
|
||||
_name = name;
|
||||
_holder = holder;
|
||||
_signature = new (CURRENT_ENV->arena()) ciSignature(_holder, constantPoolHandle(), signature);
|
||||
_intrinsic_id = vmIntrinsics::_none;
|
||||
_liveness = NULL;
|
||||
_can_be_statically_bound = false;
|
||||
_method_blocks = NULL;
|
||||
_method_data = NULL;
|
||||
ciSymbol* name,
|
||||
ciSymbol* signature,
|
||||
ciInstanceKlass* accessor) :
|
||||
ciObject(ciMethodKlass::make()),
|
||||
_name( name),
|
||||
_holder( holder),
|
||||
_intrinsic_id( vmIntrinsics::_none),
|
||||
_liveness( NULL),
|
||||
_can_be_statically_bound(false),
|
||||
_method_blocks( NULL),
|
||||
_method_data( NULL)
|
||||
#if defined(COMPILER2) || defined(SHARK)
|
||||
_flow = NULL;
|
||||
_bcea = NULL;
|
||||
,
|
||||
_flow( NULL),
|
||||
_bcea( NULL)
|
||||
#endif // COMPILER2 || SHARK
|
||||
{
|
||||
// Usually holder and accessor are the same type but in some cases
|
||||
// the holder has the wrong class loader (e.g. invokedynamic call
|
||||
// sites) so we pass the accessor.
|
||||
_signature = new (CURRENT_ENV->arena()) ciSignature(accessor, constantPoolHandle(), signature);
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,7 +88,7 @@ class ciMethod : public ciObject {
|
||||
#endif
|
||||
|
||||
ciMethod(methodHandle h_m);
|
||||
ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature);
|
||||
ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor);
|
||||
|
||||
methodOop get_methodOop() const {
|
||||
methodOop m = (methodOop)get_oop();
|
||||
|
@ -374,20 +374,32 @@ ciObject* ciObjectFactory::create_new_object(oop o) {
|
||||
// unloaded method. This may need to change.
|
||||
ciMethod* ciObjectFactory::get_unloaded_method(ciInstanceKlass* holder,
|
||||
ciSymbol* name,
|
||||
ciSymbol* signature) {
|
||||
for (int i=0; i<_unloaded_methods->length(); i++) {
|
||||
ciSymbol* signature,
|
||||
ciInstanceKlass* accessor) {
|
||||
ciSignature* that = NULL;
|
||||
for (int i = 0; i < _unloaded_methods->length(); i++) {
|
||||
ciMethod* entry = _unloaded_methods->at(i);
|
||||
if (entry->holder()->equals(holder) &&
|
||||
entry->name()->equals(name) &&
|
||||
entry->signature()->as_symbol()->equals(signature)) {
|
||||
// We've found a match.
|
||||
return entry;
|
||||
// Short-circuit slow resolve.
|
||||
if (entry->signature()->accessing_klass() == accessor) {
|
||||
// We've found a match.
|
||||
return entry;
|
||||
} else {
|
||||
// Lazily create ciSignature
|
||||
if (that == NULL) that = new (arena()) ciSignature(accessor, constantPoolHandle(), signature);
|
||||
if (entry->signature()->equals(that)) {
|
||||
// We've found a match.
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a new unloaded method. Create it and stick it in
|
||||
// the cache.
|
||||
ciMethod* new_method = new (arena()) ciMethod(holder, name, signature);
|
||||
ciMethod* new_method = new (arena()) ciMethod(holder, name, signature, accessor);
|
||||
|
||||
init_ident_of(new_method);
|
||||
_unloaded_methods->append(new_method);
|
||||
|
@ -108,7 +108,8 @@ public:
|
||||
// Get the ciMethod representing an unloaded/unfound method.
|
||||
ciMethod* get_unloaded_method(ciInstanceKlass* holder,
|
||||
ciSymbol* name,
|
||||
ciSymbol* signature);
|
||||
ciSymbol* signature,
|
||||
ciInstanceKlass* accessor);
|
||||
|
||||
// Get a ciKlass representing an unloaded klass.
|
||||
ciKlass* get_unloaded_klass(ciKlass* accessing_klass,
|
||||
|
@ -80,7 +80,7 @@ ciSignature::ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciS
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciSignature::return_ciType
|
||||
// ciSignature::return_type
|
||||
//
|
||||
// What is the return type of this signature?
|
||||
ciType* ciSignature::return_type() const {
|
||||
@ -88,7 +88,7 @@ ciType* ciSignature::return_type() const {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciSignature::ciType_at
|
||||
// ciSignature::type_at
|
||||
//
|
||||
// What is the type of the index'th element of this
|
||||
// signature?
|
||||
@ -98,6 +98,24 @@ ciType* ciSignature::type_at(int index) const {
|
||||
return _types->at(index);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciSignature::equals
|
||||
//
|
||||
// Compare this signature to another one. Signatures with different
|
||||
// accessing classes but with signature-types resolved to the same
|
||||
// types are defined to be equal.
|
||||
bool ciSignature::equals(ciSignature* that) {
|
||||
// Compare signature
|
||||
if (!this->as_symbol()->equals(that->as_symbol())) return false;
|
||||
// Compare all types of the arguments
|
||||
for (int i = 0; i < _count; i++) {
|
||||
if (this->type_at(i) != that->type_at(i)) return false;
|
||||
}
|
||||
// Compare the return type
|
||||
if (this->return_type() != that->return_type()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciSignature::print_signature
|
||||
void ciSignature::print_signature() {
|
||||
|
@ -43,6 +43,7 @@ private:
|
||||
int _count;
|
||||
|
||||
friend class ciMethod;
|
||||
friend class ciObjectFactory;
|
||||
|
||||
ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
|
||||
|
||||
@ -52,6 +53,7 @@ private:
|
||||
|
||||
public:
|
||||
ciSymbol* as_symbol() const { return _symbol; }
|
||||
ciKlass* accessing_klass() const { return _accessing_klass; }
|
||||
|
||||
ciType* return_type() const;
|
||||
ciType* type_at(int index) const;
|
||||
@ -59,6 +61,8 @@ public:
|
||||
int size() const { return _size; }
|
||||
int count() const { return _count; }
|
||||
|
||||
bool equals(ciSignature* that);
|
||||
|
||||
void print_signature();
|
||||
void print();
|
||||
};
|
||||
|
@ -503,12 +503,8 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) {
|
||||
// Allocate mirror (java.lang.Class instance)
|
||||
Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
|
||||
// Setup indirections
|
||||
mirror->obj_field_put(_klass_offset, k());
|
||||
k->set_java_mirror(mirror());
|
||||
|
||||
instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
|
||||
java_lang_Class::set_oop_size(mirror(), mk->instance_size(k));
|
||||
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
|
||||
|
||||
// It might also have a component mirror. This mirror must already exist.
|
||||
@ -571,9 +567,10 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic
|
||||
assert(aklass != NULL, "correct bootstrap");
|
||||
set_array_klass(java_class, aklass);
|
||||
}
|
||||
#ifdef ASSERT
|
||||
instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass());
|
||||
java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL)));
|
||||
java_lang_Class::set_static_oop_field_count(java_class, 0);
|
||||
assert(java_lang_Class::static_oop_field_count(java_class) == 0, "should have been zeroed by allocation");
|
||||
#endif
|
||||
return java_class;
|
||||
}
|
||||
|
||||
@ -587,6 +584,12 @@ klassOop java_lang_Class::as_klassOop(oop java_class) {
|
||||
}
|
||||
|
||||
|
||||
void java_lang_Class::set_klass(oop java_class, klassOop klass) {
|
||||
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
|
||||
java_class->obj_field_put(_klass_offset, klass);
|
||||
}
|
||||
|
||||
|
||||
void java_lang_Class::print_signature(oop java_class, outputStream* st) {
|
||||
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
|
||||
Symbol* name = NULL;
|
||||
|
@ -188,6 +188,7 @@ class java_lang_Class : AllStatic {
|
||||
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
|
||||
// Conversion
|
||||
static klassOop as_klassOop(oop java_class);
|
||||
static void set_klass(oop java_class, klassOop klass);
|
||||
static BasicType as_BasicType(oop java_class, klassOop* reference_klass = NULL);
|
||||
static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) {
|
||||
klassOop refk_oop = NULL;
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
// Only bother with this argument setup if dtrace is available
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL8(hotspot, compiled__method__load,
|
||||
const char*, int, const char*, int, const char*, int, void*, size_t);
|
||||
|
||||
@ -69,6 +70,21 @@ HS_DTRACE_PROBE_DECL6(hotspot, compiled__method__unload,
|
||||
signature->bytes(), signature->utf8_length()); \
|
||||
} \
|
||||
}
|
||||
#else /* USDT2 */
|
||||
#define DTRACE_METHOD_UNLOAD_PROBE(method) \
|
||||
{ \
|
||||
methodOop m = (method); \
|
||||
if (m != NULL) { \
|
||||
Symbol* klass_name = m->klass_name(); \
|
||||
Symbol* name = m->name(); \
|
||||
Symbol* signature = m->signature(); \
|
||||
HOTSPOT_COMPILED_METHOD_UNLOAD( \
|
||||
(char *) klass_name->bytes(), klass_name->utf8_length(), \
|
||||
(char *) name->bytes(), name->utf8_length(), \
|
||||
(char *) signature->bytes(), signature->utf8_length()); \
|
||||
} \
|
||||
}
|
||||
#endif /* USDT2 */
|
||||
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
@ -1473,6 +1489,7 @@ bool nmethod::can_unload(BoolObjectClosure* is_alive,
|
||||
void nmethod::post_compiled_method_load_event() {
|
||||
|
||||
methodOop moop = method();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE8(hotspot, compiled__method__load,
|
||||
moop->klass_name()->bytes(),
|
||||
moop->klass_name()->utf8_length(),
|
||||
@ -1481,6 +1498,16 @@ void nmethod::post_compiled_method_load_event() {
|
||||
moop->signature()->bytes(),
|
||||
moop->signature()->utf8_length(),
|
||||
insts_begin(), insts_size());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_COMPILED_METHOD_LOAD(
|
||||
(char *) moop->klass_name()->bytes(),
|
||||
moop->klass_name()->utf8_length(),
|
||||
(char *) moop->name()->bytes(),
|
||||
moop->name()->utf8_length(),
|
||||
(char *) moop->signature()->bytes(),
|
||||
moop->signature()->utf8_length(),
|
||||
insts_begin(), insts_size());
|
||||
#endif /* USDT2 */
|
||||
|
||||
if (JvmtiExport::should_post_compiled_method_load() ||
|
||||
JvmtiExport::should_post_compiled_method_unload()) {
|
||||
|
@ -58,6 +58,7 @@
|
||||
|
||||
// Only bother with this argument setup if dtrace is available
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL8(hotspot, method__compile__begin,
|
||||
char*, intptr_t, char*, intptr_t, char*, intptr_t, char*, intptr_t);
|
||||
HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end,
|
||||
@ -89,6 +90,35 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end,
|
||||
signature->bytes(), signature->utf8_length(), (success)); \
|
||||
}
|
||||
|
||||
#else /* USDT2 */
|
||||
|
||||
#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) \
|
||||
{ \
|
||||
char* comp_name = (char*)(compiler)->name(); \
|
||||
Symbol* klass_name = (method)->klass_name(); \
|
||||
Symbol* name = (method)->name(); \
|
||||
Symbol* signature = (method)->signature(); \
|
||||
HOTSPOT_METHOD_COMPILE_BEGIN( \
|
||||
comp_name, strlen(comp_name), \
|
||||
(char *) klass_name->bytes(), klass_name->utf8_length(), \
|
||||
(char *) name->bytes(), name->utf8_length(), \
|
||||
(char *) signature->bytes(), signature->utf8_length()); \
|
||||
}
|
||||
|
||||
#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) \
|
||||
{ \
|
||||
char* comp_name = (char*)(compiler)->name(); \
|
||||
Symbol* klass_name = (method)->klass_name(); \
|
||||
Symbol* name = (method)->name(); \
|
||||
Symbol* signature = (method)->signature(); \
|
||||
HOTSPOT_METHOD_COMPILE_END( \
|
||||
comp_name, strlen(comp_name), \
|
||||
(char *) klass_name->bytes(), klass_name->utf8_length(), \
|
||||
(char *) name->bytes(), name->utf8_length(), \
|
||||
(char *) signature->bytes(), signature->utf8_length(), (success)); \
|
||||
}
|
||||
#endif /* USDT2 */
|
||||
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method)
|
||||
|
@ -30,11 +30,15 @@
|
||||
#include "memory/gcLocker.inline.hpp"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
#include "utilities/dtrace.hpp"
|
||||
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL(hs_private, cms__initmark__begin);
|
||||
HS_DTRACE_PROBE_DECL(hs_private, cms__initmark__end);
|
||||
|
||||
HS_DTRACE_PROBE_DECL(hs_private, cms__remark__begin);
|
||||
HS_DTRACE_PROBE_DECL(hs_private, cms__remark__end);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// Methods in abstract class VM_CMS_Operation
|
||||
@ -129,7 +133,12 @@ void VM_CMS_Initial_Mark::doit() {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hs_private, cms__initmark__begin);
|
||||
#else /* USDT2 */
|
||||
HS_PRIVATE_CMS_INITMARK_BEGIN(
|
||||
);
|
||||
#endif /* USDT2 */
|
||||
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
|
||||
@ -140,7 +149,12 @@ void VM_CMS_Initial_Mark::doit() {
|
||||
_collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial);
|
||||
|
||||
VM_CMS_Operation::verify_after_gc();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hs_private, cms__initmark__end);
|
||||
#else /* USDT2 */
|
||||
HS_PRIVATE_CMS_INITMARK_END(
|
||||
);
|
||||
#endif /* USDT2 */
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
@ -151,7 +165,12 @@ void VM_CMS_Final_Remark::doit() {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hs_private, cms__remark__begin);
|
||||
#else /* USDT2 */
|
||||
HS_PRIVATE_CMS_REMARK_BEGIN(
|
||||
);
|
||||
#endif /* USDT2 */
|
||||
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
GCCauseSetter gccs(gch, GCCause::_cms_final_remark);
|
||||
@ -162,7 +181,12 @@ void VM_CMS_Final_Remark::doit() {
|
||||
_collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal);
|
||||
|
||||
VM_CMS_Operation::verify_after_gc();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hs_private, cms__remark__end);
|
||||
#else /* USDT2 */
|
||||
HS_PRIVATE_CMS_REMARK_END(
|
||||
);
|
||||
#endif /* USDT2 */
|
||||
}
|
||||
|
||||
// VM operation to invoke a concurrent collection of a
|
||||
|
@ -1816,9 +1816,7 @@ void ConcurrentMark::cleanup() {
|
||||
|
||||
// this will also free any regions totally full of garbage objects,
|
||||
// and sort the regions.
|
||||
g1h->g1_policy()->record_concurrent_mark_cleanup_end(
|
||||
g1_par_note_end_task.freed_bytes(),
|
||||
g1_par_note_end_task.max_live_bytes());
|
||||
g1h->g1_policy()->record_concurrent_mark_cleanup_end();
|
||||
|
||||
// Statistics.
|
||||
double end = os::elapsedTime();
|
||||
|
@ -215,19 +215,19 @@ void ConcurrentMarkThread::run() {
|
||||
gclog_or_tty->print_cr("[GC concurrent-cleanup-start]");
|
||||
}
|
||||
|
||||
// Now do the remainder of the cleanup operation.
|
||||
// Now do the concurrent cleanup operation.
|
||||
_cm->completeCleanup();
|
||||
// Notify anyone who's waiting that there are no more free
|
||||
// regions coming. We have to do this before we join the STS,
|
||||
// otherwise we might deadlock: a GC worker could be blocked
|
||||
// waiting for the notification whereas this thread will be
|
||||
// blocked for the pause to finish while it's trying to join
|
||||
// the STS, which is conditional on the GC workers finishing.
|
||||
g1h->reset_free_regions_coming();
|
||||
|
||||
_sts.join();
|
||||
g1_policy->record_concurrent_mark_cleanup_completed();
|
||||
_sts.leave();
|
||||
// Notify anyone who's waiting that there are no more free
|
||||
// regions coming. We have to do this before we join the STS
|
||||
// (in fact, we should not attempt to join the STS in the
|
||||
// interval between finishing the cleanup pause and clearing
|
||||
// the free_regions_coming flag) otherwise we might deadlock:
|
||||
// a GC worker could be blocked waiting for the notification
|
||||
// whereas this thread will be blocked for the pause to finish
|
||||
// while it's trying to join the STS, which is conditional on
|
||||
// the GC workers finishing.
|
||||
g1h->reset_free_regions_coming();
|
||||
|
||||
double cleanup_end_sec = os::elapsedTime();
|
||||
if (PrintGC) {
|
||||
@ -240,6 +240,36 @@ void ConcurrentMarkThread::run() {
|
||||
guarantee(cm()->cleanup_list_is_empty(),
|
||||
"at this point there should be no regions on the cleanup list");
|
||||
|
||||
// There is a tricky race before recording that the concurrent
|
||||
// cleanup has completed and a potential Full GC starting around
|
||||
// the same time. We want to make sure that the Full GC calls
|
||||
// abort() on concurrent mark after
|
||||
// record_concurrent_mark_cleanup_completed(), since abort() is
|
||||
// the method that will reset the concurrent mark state. If we
|
||||
// end up calling record_concurrent_mark_cleanup_completed()
|
||||
// after abort() then we might incorrectly undo some of the work
|
||||
// abort() did. Checking the has_aborted() flag after joining
|
||||
// the STS allows the correct ordering of the two methods. There
|
||||
// are two scenarios:
|
||||
//
|
||||
// a) If we reach here before the Full GC, the fact that we have
|
||||
// joined the STS means that the Full GC cannot start until we
|
||||
// leave the STS, so record_concurrent_mark_cleanup_completed()
|
||||
// will complete before abort() is called.
|
||||
//
|
||||
// b) If we reach here during the Full GC, we'll be held up from
|
||||
// joining the STS until the Full GC is done, which means that
|
||||
// abort() will have completed and has_aborted() will return
|
||||
// true to prevent us from calling
|
||||
// record_concurrent_mark_cleanup_completed() (and, in fact, it's
|
||||
// not needed any more as the concurrent mark state has been
|
||||
// already reset).
|
||||
_sts.join();
|
||||
if (!cm()->has_aborted()) {
|
||||
g1_policy->record_concurrent_mark_cleanup_completed();
|
||||
}
|
||||
_sts.leave();
|
||||
|
||||
if (cm()->has_aborted()) {
|
||||
if (PrintGC) {
|
||||
gclog_or_tty->date_stamp(PrintGCDateStamps);
|
||||
@ -248,7 +278,7 @@ void ConcurrentMarkThread::run() {
|
||||
}
|
||||
}
|
||||
|
||||
// we now want to allow clearing of the marking bitmap to be
|
||||
// We now want to allow clearing of the marking bitmap to be
|
||||
// suspended by a collection pause.
|
||||
_sts.join();
|
||||
_cm->clearNextBitmap();
|
||||
|
@ -2011,8 +2011,6 @@ jint G1CollectedHeap::initialize() {
|
||||
// Perform any initialization actions delegated to the policy.
|
||||
g1_policy()->init();
|
||||
|
||||
g1_policy()->note_start_of_mark_thread();
|
||||
|
||||
_refine_cte_cl =
|
||||
new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(),
|
||||
g1_rem_set(),
|
||||
@ -3960,9 +3958,6 @@ void G1CollectedHeap::remove_self_forwarding_pointers() {
|
||||
// _next_top_at_mark_start == top, _next_marked_bytes == 0
|
||||
// _next_marked_bytes == next_marked_bytes.
|
||||
}
|
||||
|
||||
// Now make sure the region has the right index in the sorted array.
|
||||
g1_policy()->note_change_in_marked_bytes(cur);
|
||||
}
|
||||
cur = cur->next_in_collection_set();
|
||||
}
|
||||
@ -5073,7 +5068,7 @@ public:
|
||||
|
||||
// Select discovered lists [i, i+stride, i+2*stride,...,limit)
|
||||
for (int idx = i; idx < limit; idx += stride) {
|
||||
DiscoveredList& ref_list = rp->discovered_soft_refs()[idx];
|
||||
DiscoveredList& ref_list = rp->discovered_refs()[idx];
|
||||
|
||||
DiscoveredListIterator iter(ref_list, &keep_alive, &always_alive);
|
||||
while (iter.has_next()) {
|
||||
|
@ -225,16 +225,12 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
||||
_recent_CS_bytes_surviving(new TruncatedSeq(NumPrevPausesForHeuristics)),
|
||||
|
||||
_recent_avg_pause_time_ratio(0.0),
|
||||
_num_markings(0),
|
||||
_n_marks(0),
|
||||
_n_pauses_at_mark_end(0),
|
||||
|
||||
_all_full_gc_times_ms(new NumberSeq()),
|
||||
|
||||
// G1PausesBtwnConcMark defaults to -1
|
||||
// so the hack is to do the cast QQQ FIXME
|
||||
_pauses_btwn_concurrent_mark((size_t)G1PausesBtwnConcMark),
|
||||
_n_marks_since_last_pause(0),
|
||||
_initiate_conc_mark_if_possible(false),
|
||||
_during_initial_mark_pause(false),
|
||||
_should_revert_to_full_young_gcs(false),
|
||||
@ -440,6 +436,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
||||
_reserve_regions = 0;
|
||||
|
||||
initialize_all();
|
||||
_collectionSetChooser = new CollectionSetChooser();
|
||||
}
|
||||
|
||||
// Increment "i", mod "len"
|
||||
@ -921,6 +918,7 @@ void G1CollectorPolicy::record_full_collection_end() {
|
||||
// Reset survivors SurvRateGroup.
|
||||
_survivor_surv_rate_group->reset();
|
||||
update_young_list_target_length();
|
||||
_collectionSetChooser->updateAfterFullCollection();
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::record_stop_world_start() {
|
||||
@ -1029,39 +1027,7 @@ void G1CollectorPolicy::record_concurrent_mark_cleanup_start() {
|
||||
_mark_cleanup_start_sec = os::elapsedTime();
|
||||
}
|
||||
|
||||
void
|
||||
G1CollectorPolicy::record_concurrent_mark_cleanup_end(size_t freed_bytes,
|
||||
size_t max_live_bytes) {
|
||||
record_concurrent_mark_cleanup_end_work1(freed_bytes, max_live_bytes);
|
||||
record_concurrent_mark_cleanup_end_work2();
|
||||
}
|
||||
|
||||
void
|
||||
G1CollectorPolicy::
|
||||
record_concurrent_mark_cleanup_end_work1(size_t freed_bytes,
|
||||
size_t max_live_bytes) {
|
||||
if (_n_marks < 2) {
|
||||
_n_marks++;
|
||||
}
|
||||
}
|
||||
|
||||
// The important thing about this is that it includes "os::elapsedTime".
|
||||
void G1CollectorPolicy::record_concurrent_mark_cleanup_end_work2() {
|
||||
double end_time_sec = os::elapsedTime();
|
||||
double elapsed_time_ms = (end_time_sec - _mark_cleanup_start_sec)*1000.0;
|
||||
_concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
|
||||
_cur_mark_stop_world_time_ms += elapsed_time_ms;
|
||||
_prev_collection_pause_end_ms += elapsed_time_ms;
|
||||
|
||||
_mmu_tracker->add_pause(_mark_cleanup_start_sec, end_time_sec, true);
|
||||
|
||||
_num_markings++;
|
||||
_n_pauses_at_mark_end = _n_pauses;
|
||||
_n_marks_since_last_pause++;
|
||||
}
|
||||
|
||||
void
|
||||
G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
|
||||
void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
|
||||
_should_revert_to_full_young_gcs = false;
|
||||
_last_full_young_gc = true;
|
||||
_in_marking_window = false;
|
||||
@ -1501,11 +1467,9 @@ void G1CollectorPolicy::record_collection_pause_end() {
|
||||
summary->record_other_time_ms(other_time_ms);
|
||||
}
|
||||
for (int i = 0; i < _aux_num; ++i)
|
||||
if (_cur_aux_times_set[i])
|
||||
if (_cur_aux_times_set[i]) {
|
||||
_all_aux_times_ms[i].add(_cur_aux_times_ms[i]);
|
||||
|
||||
// Reset marks-between-pauses counter.
|
||||
_n_marks_since_last_pause = 0;
|
||||
}
|
||||
|
||||
// Update the efficiency-since-mark vars.
|
||||
double proc_ms = elapsed_ms * (double) _parallel_gc_threads;
|
||||
@ -1729,6 +1693,8 @@ void G1CollectorPolicy::record_collection_pause_end() {
|
||||
double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
|
||||
adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
|
||||
// </NEW PREDICTION>
|
||||
|
||||
assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
|
||||
}
|
||||
|
||||
#define EXT_SIZE_FORMAT "%d%s"
|
||||
@ -2156,10 +2122,6 @@ size_t G1CollectorPolicy::expansion_amount() {
|
||||
}
|
||||
}
|
||||
|
||||
void G1CollectorPolicy::note_start_of_mark_thread() {
|
||||
_mark_thread_startup_sec = os::elapsedTime();
|
||||
}
|
||||
|
||||
class CountCSClosure: public HeapRegionClosure {
|
||||
G1CollectorPolicy* _g1_policy;
|
||||
public:
|
||||
@ -2446,7 +2408,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool G1CollectorPolicy_BestRegionsFirst::assertMarkedBytesDataOK() {
|
||||
bool G1CollectorPolicy::assertMarkedBytesDataOK() {
|
||||
HRSortIndexIsOKClosure cl(_collectionSetChooser);
|
||||
_g1->heap_region_iterate(&cl);
|
||||
return true;
|
||||
@ -2532,12 +2494,6 @@ G1CollectorPolicy::decide_on_conc_mark_initiation() {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G1CollectorPolicy_BestRegionsFirst::
|
||||
record_collection_pause_start(double start_time_sec, size_t start_used) {
|
||||
G1CollectorPolicy::record_collection_pause_start(start_time_sec, start_used);
|
||||
}
|
||||
|
||||
class KnownGarbageClosure: public HeapRegionClosure {
|
||||
CollectionSetChooser* _hrSorted;
|
||||
|
||||
@ -2645,20 +2601,20 @@ public:
|
||||
};
|
||||
|
||||
void
|
||||
G1CollectorPolicy_BestRegionsFirst::
|
||||
record_concurrent_mark_cleanup_end(size_t freed_bytes,
|
||||
size_t max_live_bytes) {
|
||||
double start;
|
||||
if (G1PrintParCleanupStats) start = os::elapsedTime();
|
||||
record_concurrent_mark_cleanup_end_work1(freed_bytes, max_live_bytes);
|
||||
G1CollectorPolicy::record_concurrent_mark_cleanup_end() {
|
||||
double start_sec;
|
||||
if (G1PrintParCleanupStats) {
|
||||
start_sec = os::elapsedTime();
|
||||
}
|
||||
|
||||
_collectionSetChooser->clearMarkedHeapRegions();
|
||||
double clear_marked_end;
|
||||
double clear_marked_end_sec;
|
||||
if (G1PrintParCleanupStats) {
|
||||
clear_marked_end = os::elapsedTime();
|
||||
gclog_or_tty->print_cr(" clear marked regions + work1: %8.3f ms.",
|
||||
(clear_marked_end - start)*1000.0);
|
||||
clear_marked_end_sec = os::elapsedTime();
|
||||
gclog_or_tty->print_cr(" clear marked regions: %8.3f ms.",
|
||||
(clear_marked_end_sec - start_sec) * 1000.0);
|
||||
}
|
||||
|
||||
if (G1CollectedHeap::use_parallel_gc_threads()) {
|
||||
const size_t OverpartitionFactor = 4;
|
||||
const size_t MinWorkUnit = 8;
|
||||
@ -2677,27 +2633,25 @@ record_concurrent_mark_cleanup_end(size_t freed_bytes,
|
||||
KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
|
||||
_g1->heap_region_iterate(&knownGarbagecl);
|
||||
}
|
||||
double known_garbage_end;
|
||||
double known_garbage_end_sec;
|
||||
if (G1PrintParCleanupStats) {
|
||||
known_garbage_end = os::elapsedTime();
|
||||
known_garbage_end_sec = os::elapsedTime();
|
||||
gclog_or_tty->print_cr(" compute known garbage: %8.3f ms.",
|
||||
(known_garbage_end - clear_marked_end)*1000.0);
|
||||
}
|
||||
_collectionSetChooser->sortMarkedHeapRegions();
|
||||
double sort_end;
|
||||
if (G1PrintParCleanupStats) {
|
||||
sort_end = os::elapsedTime();
|
||||
gclog_or_tty->print_cr(" sorting: %8.3f ms.",
|
||||
(sort_end - known_garbage_end)*1000.0);
|
||||
(known_garbage_end_sec - clear_marked_end_sec) * 1000.0);
|
||||
}
|
||||
|
||||
record_concurrent_mark_cleanup_end_work2();
|
||||
double work2_end;
|
||||
_collectionSetChooser->sortMarkedHeapRegions();
|
||||
double end_sec = os::elapsedTime();
|
||||
if (G1PrintParCleanupStats) {
|
||||
work2_end = os::elapsedTime();
|
||||
gclog_or_tty->print_cr(" work2: %8.3f ms.",
|
||||
(work2_end - sort_end)*1000.0);
|
||||
gclog_or_tty->print_cr(" sorting: %8.3f ms.",
|
||||
(end_sec - known_garbage_end_sec) * 1000.0);
|
||||
}
|
||||
|
||||
double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
|
||||
_concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
|
||||
_cur_mark_stop_world_time_ms += elapsed_time_ms;
|
||||
_prev_collection_pause_end_ms += elapsed_time_ms;
|
||||
_mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true);
|
||||
}
|
||||
|
||||
// Add the heap region at the head of the non-incremental collection set
|
||||
@ -2912,9 +2866,7 @@ void G1CollectorPolicy::print_collection_set(HeapRegion* list_head, outputStream
|
||||
}
|
||||
#endif // !PRODUCT
|
||||
|
||||
void
|
||||
G1CollectorPolicy_BestRegionsFirst::choose_collection_set(
|
||||
double target_pause_time_ms) {
|
||||
void G1CollectorPolicy::choose_collection_set(double target_pause_time_ms) {
|
||||
// Set this here - in case we're not doing young collections.
|
||||
double non_young_start_time_sec = os::elapsedTime();
|
||||
|
||||
@ -3115,14 +3067,3 @@ G1CollectorPolicy_BestRegionsFirst::choose_collection_set(
|
||||
_recorded_non_young_cset_choice_time_ms =
|
||||
(non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
|
||||
}
|
||||
|
||||
void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() {
|
||||
G1CollectorPolicy::record_full_collection_end();
|
||||
_collectionSetChooser->updateAfterFullCollection();
|
||||
}
|
||||
|
||||
void G1CollectorPolicy_BestRegionsFirst::
|
||||
record_collection_pause_end() {
|
||||
G1CollectorPolicy::record_collection_pause_end();
|
||||
assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
};
|
||||
|
||||
class G1CollectorPolicy: public CollectorPolicy {
|
||||
protected:
|
||||
private:
|
||||
// The number of pauses during the execution.
|
||||
long _n_pauses;
|
||||
|
||||
@ -106,10 +106,7 @@ protected:
|
||||
initialize_perm_generation(PermGen::MarkSweepCompact);
|
||||
}
|
||||
|
||||
virtual size_t default_init_heap_size() {
|
||||
// Pick some reasonable default.
|
||||
return 8*M;
|
||||
}
|
||||
CollectionSetChooser* _collectionSetChooser;
|
||||
|
||||
double _cur_collection_start_sec;
|
||||
size_t _cur_collection_pause_used_at_start_bytes;
|
||||
@ -316,7 +313,6 @@ private:
|
||||
double update_rs_processed_buffers,
|
||||
double goal_ms);
|
||||
|
||||
protected:
|
||||
double _pause_time_target_ms;
|
||||
double _recorded_young_cset_choice_time_ms;
|
||||
double _recorded_non_young_cset_choice_time_ms;
|
||||
@ -554,7 +550,7 @@ public:
|
||||
return _short_lived_surv_rate_group->accum_surv_rate_pred(age);
|
||||
}
|
||||
|
||||
protected:
|
||||
private:
|
||||
void print_stats(int level, const char* str, double value);
|
||||
void print_stats(int level, const char* str, int value);
|
||||
|
||||
@ -588,10 +584,6 @@ protected:
|
||||
// Statistics kept per GC stoppage, pause or full.
|
||||
TruncatedSeq* _recent_prev_end_times_for_all_gcs_sec;
|
||||
|
||||
// We track markings.
|
||||
int _num_markings;
|
||||
double _mark_thread_startup_sec; // Time at startup of marking thread
|
||||
|
||||
// Add a new GC of the given duration and end time to the record.
|
||||
void update_recent_gc_times(double end_time_sec, double elapsed_ms);
|
||||
|
||||
@ -664,12 +656,6 @@ protected:
|
||||
// young list/collection set).
|
||||
size_t _inc_cset_predicted_bytes_to_copy;
|
||||
|
||||
// Info about marking.
|
||||
int _n_marks; // Sticky at 2, so we know when we've done at least 2.
|
||||
|
||||
// The number of collection pauses at the end of the last mark.
|
||||
size_t _n_pauses_at_mark_end;
|
||||
|
||||
// Stash a pointer to the g1 heap.
|
||||
G1CollectedHeap* _g1;
|
||||
|
||||
@ -737,8 +723,6 @@ protected:
|
||||
// Number of pauses between concurrent marking.
|
||||
size_t _pauses_btwn_concurrent_mark;
|
||||
|
||||
size_t _n_marks_since_last_pause;
|
||||
|
||||
// At the end of a pause we check the heap occupancy and we decide
|
||||
// whether we will start a marking cycle during the next pause. If
|
||||
// we decide that we want to do that, we will set this parameter to
|
||||
@ -810,6 +794,11 @@ protected:
|
||||
bool predict_will_fit(size_t young_length, double base_time_ms,
|
||||
size_t base_free_regions, double target_pause_time_ms);
|
||||
|
||||
// Count the number of bytes used in the CS.
|
||||
void count_CS_bytes_used();
|
||||
|
||||
void update_young_list_size_using_newratio(size_t number_of_heap_regions);
|
||||
|
||||
public:
|
||||
|
||||
G1CollectorPolicy();
|
||||
@ -836,22 +825,9 @@ public:
|
||||
// This should be called after the heap is resized.
|
||||
void record_new_heap_size(size_t new_number_of_regions);
|
||||
|
||||
protected:
|
||||
|
||||
// Count the number of bytes used in the CS.
|
||||
void count_CS_bytes_used();
|
||||
|
||||
// Together these do the base cleanup-recording work. Subclasses might
|
||||
// want to put something between them.
|
||||
void record_concurrent_mark_cleanup_end_work1(size_t freed_bytes,
|
||||
size_t max_live_bytes);
|
||||
void record_concurrent_mark_cleanup_end_work2();
|
||||
|
||||
void update_young_list_size_using_newratio(size_t number_of_heap_regions);
|
||||
|
||||
public:
|
||||
|
||||
virtual void init();
|
||||
void init();
|
||||
|
||||
// Create jstat counters for the policy.
|
||||
virtual void initialize_gc_policy_counters();
|
||||
@ -876,10 +852,9 @@ public:
|
||||
// start time, where the given number of bytes were used at the start.
|
||||
// This may involve changing the desired size of a collection set.
|
||||
|
||||
virtual void record_stop_world_start();
|
||||
void record_stop_world_start();
|
||||
|
||||
virtual void record_collection_pause_start(double start_time_sec,
|
||||
size_t start_used);
|
||||
void record_collection_pause_start(double start_time_sec, size_t start_used);
|
||||
|
||||
// Must currently be called while the world is stopped.
|
||||
void record_concurrent_mark_init_end(double
|
||||
@ -887,23 +862,22 @@ public:
|
||||
|
||||
void record_mark_closure_time(double mark_closure_time_ms);
|
||||
|
||||
virtual void record_concurrent_mark_remark_start();
|
||||
virtual void record_concurrent_mark_remark_end();
|
||||
void record_concurrent_mark_remark_start();
|
||||
void record_concurrent_mark_remark_end();
|
||||
|
||||
virtual void record_concurrent_mark_cleanup_start();
|
||||
virtual void record_concurrent_mark_cleanup_end(size_t freed_bytes,
|
||||
size_t max_live_bytes);
|
||||
virtual void record_concurrent_mark_cleanup_completed();
|
||||
void record_concurrent_mark_cleanup_start();
|
||||
void record_concurrent_mark_cleanup_end();
|
||||
void record_concurrent_mark_cleanup_completed();
|
||||
|
||||
virtual void record_concurrent_pause();
|
||||
virtual void record_concurrent_pause_end();
|
||||
void record_concurrent_pause();
|
||||
void record_concurrent_pause_end();
|
||||
|
||||
virtual void record_collection_pause_end();
|
||||
void record_collection_pause_end();
|
||||
void print_heap_transition();
|
||||
|
||||
// Record the fact that a full collection occurred.
|
||||
virtual void record_full_collection_start();
|
||||
virtual void record_full_collection_end();
|
||||
void record_full_collection_start();
|
||||
void record_full_collection_end();
|
||||
|
||||
void record_gc_worker_start_time(int worker_i, double ms) {
|
||||
_par_last_gc_worker_start_times_ms[worker_i] = ms;
|
||||
@ -1022,7 +996,7 @@ public:
|
||||
// Choose a new collection set. Marks the chosen regions as being
|
||||
// "in_collection_set", and links them together. The head and number of
|
||||
// the collection set are available via access methods.
|
||||
virtual void choose_collection_set(double target_pause_time_ms) = 0;
|
||||
void choose_collection_set(double target_pause_time_ms);
|
||||
|
||||
// The head of the list (via "next_in_collection_set()") representing the
|
||||
// current collection set.
|
||||
@ -1107,19 +1081,12 @@ public:
|
||||
|
||||
// If an expansion would be appropriate, because recent GC overhead had
|
||||
// exceeded the desired limit, return an amount to expand by.
|
||||
virtual size_t expansion_amount();
|
||||
|
||||
// note start of mark thread
|
||||
void note_start_of_mark_thread();
|
||||
|
||||
// The marked bytes of the "r" has changed; reclassify it's desirability
|
||||
// for marking. Also asserts that "r" is eligible for a CS.
|
||||
virtual void note_change_in_marked_bytes(HeapRegion* r) = 0;
|
||||
size_t expansion_amount();
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Check any appropriate marked bytes info, asserting false if
|
||||
// something's wrong, else returning "true".
|
||||
virtual bool assertMarkedBytesDataOK() = 0;
|
||||
bool assertMarkedBytesDataOK();
|
||||
#endif
|
||||
|
||||
// Print tracing information.
|
||||
@ -1182,10 +1149,10 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
//
|
||||
// Survivor regions policy.
|
||||
//
|
||||
protected:
|
||||
|
||||
// Current tenuring threshold, set to 0 if the collector reaches the
|
||||
// maximum amount of suvivors regions.
|
||||
@ -1265,51 +1232,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
// This encapsulates a particular strategy for a g1 Collector.
|
||||
//
|
||||
// Start a concurrent mark when our heap size is n bytes
|
||||
// greater then our heap size was at the last concurrent
|
||||
// mark. Where n is a function of the CMSTriggerRatio
|
||||
// and the MinHeapFreeRatio.
|
||||
//
|
||||
// Start a g1 collection pause when we have allocated the
|
||||
// average number of bytes currently being freed in
|
||||
// a collection, but only if it is at least one region
|
||||
// full
|
||||
//
|
||||
// Resize Heap based on desired
|
||||
// allocation space, where desired allocation space is
|
||||
// a function of survival rate and desired future to size.
|
||||
//
|
||||
// Choose collection set by first picking all older regions
|
||||
// which have a survival rate which beats our projected young
|
||||
// survival rate. Then fill out the number of needed regions
|
||||
// with young regions.
|
||||
|
||||
class G1CollectorPolicy_BestRegionsFirst: public G1CollectorPolicy {
|
||||
CollectionSetChooser* _collectionSetChooser;
|
||||
|
||||
virtual void choose_collection_set(double target_pause_time_ms);
|
||||
virtual void record_collection_pause_start(double start_time_sec,
|
||||
size_t start_used);
|
||||
virtual void record_concurrent_mark_cleanup_end(size_t freed_bytes,
|
||||
size_t max_live_bytes);
|
||||
virtual void record_full_collection_end();
|
||||
|
||||
public:
|
||||
G1CollectorPolicy_BestRegionsFirst() {
|
||||
_collectionSetChooser = new CollectionSetChooser();
|
||||
}
|
||||
void record_collection_pause_end();
|
||||
// This is not needed any more, after the CSet choosing code was
|
||||
// changed to use the pause prediction work. But let's leave the
|
||||
// hook in just in case.
|
||||
void note_change_in_marked_bytes(HeapRegion* r) { }
|
||||
#ifndef PRODUCT
|
||||
bool assertMarkedBytesDataOK();
|
||||
#endif
|
||||
};
|
||||
|
||||
// This should move to some place more general...
|
||||
|
||||
// If we have "n" measurements, and we've kept track of their "sum" and the
|
||||
|
@ -40,20 +40,32 @@
|
||||
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL1(hotspot, gc__begin, bool);
|
||||
HS_DTRACE_PROBE_DECL(hotspot, gc__end);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
// The same dtrace probe can't be inserted in two different files, so we
|
||||
// have to call it here, so it's only in one file. Can't create new probes
|
||||
// for the other file anymore. The dtrace probes have to remain stable.
|
||||
void VM_GC_Operation::notify_gc_begin(bool full) {
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE1(hotspot, gc__begin, full);
|
||||
HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_GC_BEGIN(
|
||||
full);
|
||||
#endif /* USDT2 */
|
||||
}
|
||||
|
||||
void VM_GC_Operation::notify_gc_end() {
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hotspot, gc__end);
|
||||
HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_GC_END(
|
||||
);
|
||||
#endif /* USDT2 */
|
||||
}
|
||||
|
||||
void VM_GC_Operation::acquire_pending_list_lock() {
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "gc_interface/collectedHeap.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/instanceMirrorKlass.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "services/heapDumper.hpp"
|
||||
#ifdef TARGET_OS_FAMILY_linux
|
||||
@ -436,3 +437,37 @@ void CollectedHeap::post_full_gc_dump() {
|
||||
inspector.doit();
|
||||
}
|
||||
}
|
||||
|
||||
oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS) {
|
||||
debug_only(check_for_valid_allocation_state());
|
||||
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj;
|
||||
if (JavaObjectsInPerm) {
|
||||
obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
|
||||
} else {
|
||||
assert(ScavengeRootsInCode > 0, "must be");
|
||||
obj = common_mem_allocate_init(size, CHECK_NULL);
|
||||
}
|
||||
post_allocation_setup_common(klass, obj, size);
|
||||
assert(Universe::is_bootstrapping() ||
|
||||
!((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
|
||||
oop mirror = (oop)obj;
|
||||
|
||||
java_lang_Class::set_oop_size(mirror, size);
|
||||
|
||||
// Setup indirections
|
||||
if (!real_klass.is_null()) {
|
||||
java_lang_Class::set_klass(mirror, real_klass());
|
||||
real_klass->set_java_mirror(mirror);
|
||||
}
|
||||
|
||||
instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
|
||||
assert(size == mk->instance_size(real_klass), "should have been set");
|
||||
|
||||
// notify jvmti and dtrace
|
||||
post_allocation_notify(klass, (oop)obj);
|
||||
|
||||
return mirror;
|
||||
}
|
||||
|
@ -319,6 +319,9 @@ class CollectedHeap : public CHeapObj {
|
||||
// VM (then terminate).
|
||||
virtual void preload_and_dump(TRAPS) { ShouldNotReachHere(); }
|
||||
|
||||
// Allocate and initialize instances of Class
|
||||
static oop Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS);
|
||||
|
||||
// General obj/array allocation facilities.
|
||||
inline static oop obj_allocate(KlassHandle klass, int size, TRAPS);
|
||||
inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS);
|
||||
|
@ -105,19 +105,22 @@ ReferenceProcessor::ReferenceProcessor(MemRegion span,
|
||||
_discovery_is_mt = mt_discovery;
|
||||
_num_q = MAX2(1, mt_processing_degree);
|
||||
_max_num_q = MAX2(_num_q, mt_discovery_degree);
|
||||
_discoveredSoftRefs = NEW_C_HEAP_ARRAY(DiscoveredList,
|
||||
_discovered_refs = NEW_C_HEAP_ARRAY(DiscoveredList,
|
||||
_max_num_q * number_of_subclasses_of_ref());
|
||||
if (_discoveredSoftRefs == NULL) {
|
||||
if (_discovered_refs == NULL) {
|
||||
vm_exit_during_initialization("Could not allocated RefProc Array");
|
||||
}
|
||||
_discoveredSoftRefs = &_discovered_refs[0];
|
||||
_discoveredWeakRefs = &_discoveredSoftRefs[_max_num_q];
|
||||
_discoveredFinalRefs = &_discoveredWeakRefs[_max_num_q];
|
||||
_discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
|
||||
// Initialized all entries to NULL
|
||||
|
||||
// Initialize all entries to NULL
|
||||
for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
|
||||
_discoveredSoftRefs[i].set_head(NULL);
|
||||
_discoveredSoftRefs[i].set_length(0);
|
||||
_discovered_refs[i].set_head(NULL);
|
||||
_discovered_refs[i].set_length(0);
|
||||
}
|
||||
|
||||
// If we do barriers, cache a copy of the barrier set.
|
||||
if (discovered_list_needs_barrier) {
|
||||
_bs = Universe::heap()->barrier_set();
|
||||
@ -129,7 +132,7 @@ ReferenceProcessor::ReferenceProcessor(MemRegion span,
|
||||
void ReferenceProcessor::verify_no_references_recorded() {
|
||||
guarantee(!_discovering_refs, "Discovering refs?");
|
||||
for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
|
||||
guarantee(_discoveredSoftRefs[i].is_empty(),
|
||||
guarantee(_discovered_refs[i].is_empty(),
|
||||
"Found non-empty discovered list");
|
||||
}
|
||||
}
|
||||
@ -138,9 +141,9 @@ void ReferenceProcessor::verify_no_references_recorded() {
|
||||
void ReferenceProcessor::weak_oops_do(OopClosure* f) {
|
||||
for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
|
||||
if (UseCompressedOops) {
|
||||
f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head());
|
||||
f->do_oop((narrowOop*)_discovered_refs[i].adr_head());
|
||||
} else {
|
||||
f->do_oop((oop*)_discoveredSoftRefs[i].adr_head());
|
||||
f->do_oop((oop*)_discovered_refs[i].adr_head());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -423,15 +426,15 @@ void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr
|
||||
AbstractRefProcTaskExecutor* task_executor) {
|
||||
if (_processing_is_mt && task_executor != NULL) {
|
||||
// Parallel code
|
||||
RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
|
||||
RefProcEnqueueTask tsk(*this, _discovered_refs,
|
||||
pending_list_addr, _max_num_q);
|
||||
task_executor->execute(tsk);
|
||||
} else {
|
||||
// Serial code: call the parent class's implementation
|
||||
for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
|
||||
enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
|
||||
_discoveredSoftRefs[i].set_head(NULL);
|
||||
_discoveredSoftRefs[i].set_length(0);
|
||||
enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
|
||||
_discovered_refs[i].set_head(NULL);
|
||||
_discovered_refs[i].set_length(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -691,7 +694,7 @@ void ReferenceProcessor::abandon_partial_discovery() {
|
||||
if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
|
||||
gclog_or_tty->print_cr("\nAbandoning %s discovered list", list_name(i));
|
||||
}
|
||||
abandon_partial_discovered_list(_discoveredSoftRefs[i]);
|
||||
abandon_partial_discovered_list(_discovered_refs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -952,7 +955,7 @@ void ReferenceProcessor::clean_up_discovered_references() {
|
||||
"\nScrubbing %s discovered list of Null referents",
|
||||
list_name(i));
|
||||
}
|
||||
clean_up_discovered_reflist(_discoveredSoftRefs[i]);
|
||||
clean_up_discovered_reflist(_discovered_refs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1402,7 +1405,7 @@ void ReferenceProcessor::verify_ok_to_handle_reflists() {
|
||||
void ReferenceProcessor::clear_discovered_references() {
|
||||
guarantee(!_discovering_refs, "Discovering refs?");
|
||||
for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
|
||||
clear_discovered_references(_discoveredSoftRefs[i]);
|
||||
clear_discovered_references(_discovered_refs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,11 @@ class ReferenceProcessor : public CHeapObj {
|
||||
int _num_q;
|
||||
// The maximum MT'ness degree of the queues below
|
||||
int _max_num_q;
|
||||
// Arrays of lists of oops, one per thread
|
||||
|
||||
// Master array of discovered oops
|
||||
DiscoveredList* _discovered_refs;
|
||||
|
||||
// Arrays of lists of oops, one per thread (pointers into master array above)
|
||||
DiscoveredList* _discoveredSoftRefs;
|
||||
DiscoveredList* _discoveredWeakRefs;
|
||||
DiscoveredList* _discoveredFinalRefs;
|
||||
@ -267,7 +271,8 @@ class ReferenceProcessor : public CHeapObj {
|
||||
int num_q() { return _num_q; }
|
||||
int max_num_q() { return _max_num_q; }
|
||||
void set_active_mt_degree(int v) { _num_q = v; }
|
||||
DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
|
||||
|
||||
DiscoveredList* discovered_refs() { return _discovered_refs; }
|
||||
|
||||
ReferencePolicy* setup_policy(bool always_clear) {
|
||||
_current_soft_ref_policy = always_clear ?
|
||||
@ -411,6 +416,7 @@ class ReferenceProcessor : public CHeapObj {
|
||||
// constructor
|
||||
ReferenceProcessor():
|
||||
_span((HeapWord*)NULL, (HeapWord*)NULL),
|
||||
_discovered_refs(NULL),
|
||||
_discoveredSoftRefs(NULL), _discoveredWeakRefs(NULL),
|
||||
_discoveredFinalRefs(NULL), _discoveredPhantomRefs(NULL),
|
||||
_discovering_refs(false),
|
||||
|
@ -893,7 +893,7 @@ jint Universe::initialize_heap() {
|
||||
|
||||
} else if (UseG1GC) {
|
||||
#ifndef SERIALGC
|
||||
G1CollectorPolicy* g1p = new G1CollectorPolicy_BestRegionsFirst();
|
||||
G1CollectorPolicy* g1p = new G1CollectorPolicy();
|
||||
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
|
||||
Universe::_collectedHeap = g1h;
|
||||
#else // SERIALGC
|
||||
|
@ -80,6 +80,8 @@
|
||||
|
||||
#ifdef DTRACE_ENABLED
|
||||
|
||||
#ifndef USDT2
|
||||
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required,
|
||||
char*, intptr_t, oop, intptr_t);
|
||||
HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive,
|
||||
@ -122,6 +124,42 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
|
||||
HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \
|
||||
data, len, (clss)->class_loader(), thread_type, wait); \
|
||||
}
|
||||
#else /* USDT2 */
|
||||
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_required HOTSPOT_CLASS_INITIALIZATION_REQUIRED
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_recursive HOTSPOT_CLASS_INITIALIZATION_RECURSIVE
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_concurrent HOTSPOT_CLASS_INITIALIZATION_CONCURRENT
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_erroneous HOTSPOT_CLASS_INITIALIZATION_ERRONEOUS
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_super__failed HOTSPOT_CLASS_INITIALIZATION_SUPER_FAILED
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_clinit HOTSPOT_CLASS_INITIALIZATION_CLINIT
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_error HOTSPOT_CLASS_INITIALIZATION_ERROR
|
||||
#define HOTSPOT_CLASS_INITIALIZATION_end HOTSPOT_CLASS_INITIALIZATION_END
|
||||
#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) \
|
||||
{ \
|
||||
char* data = NULL; \
|
||||
int len = 0; \
|
||||
Symbol* name = (clss)->name(); \
|
||||
if (name != NULL) { \
|
||||
data = (char*)name->bytes(); \
|
||||
len = name->utf8_length(); \
|
||||
} \
|
||||
HOTSPOT_CLASS_INITIALIZATION_##type( \
|
||||
data, len, (clss)->class_loader(), thread_type); \
|
||||
}
|
||||
|
||||
#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
|
||||
{ \
|
||||
char* data = NULL; \
|
||||
int len = 0; \
|
||||
Symbol* name = (clss)->name(); \
|
||||
if (name != NULL) { \
|
||||
data = (char*)name->bytes(); \
|
||||
len = name->utf8_length(); \
|
||||
} \
|
||||
HOTSPOT_CLASS_INITIALIZATION_##type( \
|
||||
data, len, (clss)->class_loader(), thread_type, wait); \
|
||||
}
|
||||
#endif /* USDT2 */
|
||||
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
|
@ -288,15 +288,7 @@ instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
|
||||
// Query before forming handle.
|
||||
int size = instance_size(k);
|
||||
KlassHandle h_k(THREAD, as_klassOop());
|
||||
instanceOop i;
|
||||
|
||||
if (JavaObjectsInPerm) {
|
||||
i = (instanceOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
|
||||
} else {
|
||||
assert(ScavengeRootsInCode > 0, "must be");
|
||||
i = (instanceOop) CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
|
||||
}
|
||||
|
||||
instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -721,12 +721,7 @@ const Type *ConvF2DNode::Value( PhaseTransform *phase ) const {
|
||||
if( t == Type::TOP ) return Type::TOP;
|
||||
if( t == Type::FLOAT ) return Type::DOUBLE;
|
||||
const TypeF *tf = t->is_float_constant();
|
||||
#ifndef IA64
|
||||
return TypeD::make( (double)tf->getf() );
|
||||
#else
|
||||
float x = tf->getf();
|
||||
return TypeD::make( (x == 0.0f) ? (double)x : (double)x + ia64_double_zero );
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -997,10 +997,13 @@ JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* t
|
||||
force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc);
|
||||
|
||||
if (handler_address == NULL) {
|
||||
Handle original_exception(thread, exception());
|
||||
handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true);
|
||||
assert (handler_address != NULL, "must have compiled handler");
|
||||
// Update the exception cache only when the unwind was not forced.
|
||||
if (!force_unwind) {
|
||||
// Update the exception cache only when the unwind was not forced
|
||||
// and there didn't happen another exception during the computation of the
|
||||
// compiled exception handler.
|
||||
if (!force_unwind && original_exception() == exception()) {
|
||||
nm->add_handler_for_exception_and_pc(exception,pc,handler_address);
|
||||
}
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -79,9 +79,11 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long);
|
||||
HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int);
|
||||
HS_DTRACE_PROBE_DECL0(hotspot, thread__yield);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
/*
|
||||
NOTE about use of any ctor or function call that can trigger a safepoint/GC:
|
||||
@ -2816,7 +2818,11 @@ JVM_END
|
||||
JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass))
|
||||
JVMWrapper("JVM_Yield");
|
||||
if (os::dont_yield()) return;
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE0(hotspot, thread__yield);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_YIELD();
|
||||
#endif /* USDT2 */
|
||||
// When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.
|
||||
// Critical for similar threading behaviour
|
||||
if (ConvertYieldToSleep) {
|
||||
@ -2842,7 +2848,12 @@ JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
|
||||
// And set new thread state to SLEEPING.
|
||||
JavaThreadSleepState jtss(thread);
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_SLEEP_BEGIN(
|
||||
millis);
|
||||
#endif /* USDT2 */
|
||||
|
||||
if (millis == 0) {
|
||||
// When ConvertSleepToYield is on, this matches the classic VM implementation of
|
||||
@ -2864,7 +2875,12 @@ JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
|
||||
// An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
|
||||
// us while we were sleeping. We do not overwrite those.
|
||||
if (!HAS_PENDING_EXCEPTION) {
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_SLEEP_END(
|
||||
1);
|
||||
#endif /* USDT2 */
|
||||
// TODO-FIXME: THROW_MSG returns which means we will not call set_state()
|
||||
// to properly restore the thread state. That's likely wrong.
|
||||
THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
|
||||
@ -2872,7 +2888,12 @@ JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
|
||||
}
|
||||
thread->osthread()->set_state(old_state);
|
||||
}
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_SLEEP_END(
|
||||
0);
|
||||
#endif /* USDT2 */
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
|
||||
@ -2990,6 +3011,20 @@ JVM_ENTRY(void, JVM_DumpAllStacks(JNIEnv* env, jclass))
|
||||
}
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))
|
||||
JVMWrapper("JVM_SetNativeThreadName");
|
||||
ResourceMark rm(THREAD);
|
||||
oop java_thread = JNIHandles::resolve_non_null(jthread);
|
||||
JavaThread* thr = java_lang_Thread::thread(java_thread);
|
||||
// Thread naming only supported for the current thread, doesn't work for
|
||||
// target threads.
|
||||
if (Thread::current() == thr && !thr->has_attached_via_jni()) {
|
||||
// we don't set the name of an attached thread to avoid stepping
|
||||
// on other programs
|
||||
const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
|
||||
os::set_native_thread_name(thread_name);
|
||||
}
|
||||
JVM_END
|
||||
|
||||
// java.lang.SecurityManager ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -291,6 +291,9 @@ JVM_DumpAllStacks(JNIEnv *env, jclass unused);
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
JVM_GetAllThreads(JNIEnv *env, jclass dummy);
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name);
|
||||
|
||||
/* getStackTrace() and getAllStackTraces() method */
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads);
|
||||
|
@ -1387,10 +1387,8 @@ bool MethodHandleCompiler::fetch_counts(ArgToken arg1, ArgToken arg2) {
|
||||
int total = count1 + count2;
|
||||
if (count1 != -1 && count2 != -1 && total != 0) {
|
||||
// Normalize the collect counts to the invoke_count
|
||||
tty->print("counts %d %d scaled by %d = ", count2, count1, _invoke_count);
|
||||
if (count1 != 0) _not_taken_count = (int)(_invoke_count * count1 / (double)total);
|
||||
if (count2 != 0) _taken_count = (int)(_invoke_count * count2 / (double)total);
|
||||
tty->print_cr("%d %d", _taken_count, _not_taken_count);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -42,9 +42,11 @@
|
||||
* Implementation of class sun.misc.Unsafe
|
||||
*/
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long);
|
||||
HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t);
|
||||
HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
#define MAX_OBJECT_SIZE \
|
||||
( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
|
||||
@ -1187,10 +1189,20 @@ UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time))
|
||||
UnsafeWrapper("Unsafe_Park");
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_PARK_BEGIN(
|
||||
(uintptr_t) thread->parker(), (int) isAbsolute, time);
|
||||
#endif /* USDT2 */
|
||||
JavaThreadParkedState jtps(thread, time != 0);
|
||||
thread->parker()->park(isAbsolute != 0, time);
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_PARK_END(
|
||||
(uintptr_t) thread->parker());
|
||||
#endif /* USDT2 */
|
||||
UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
|
||||
@ -1222,7 +1234,12 @@ UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
|
||||
}
|
||||
}
|
||||
if (p != NULL) {
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE1(hotspot, thread__unpark, p);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_THREAD_UNPARK(
|
||||
(uintptr_t) p);
|
||||
#endif /* USDT2 */
|
||||
p->unpark();
|
||||
}
|
||||
UNSAFE_END
|
||||
|
@ -2602,16 +2602,16 @@ SOLARIS_ONLY(
|
||||
FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false);
|
||||
FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true);
|
||||
} else if (match_option(option, "-XX:+ExtendedDTraceProbes", &tail)) {
|
||||
#ifdef SOLARIS
|
||||
#if defined(DTRACE_ENABLED)
|
||||
FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true);
|
||||
FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true);
|
||||
FLAG_SET_CMDLINE(bool, DTraceAllocProbes, true);
|
||||
FLAG_SET_CMDLINE(bool, DTraceMonitorProbes, true);
|
||||
#else // ndef SOLARIS
|
||||
#else // defined(DTRACE_ENABLED)
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"ExtendedDTraceProbes flag is only applicable on Solaris\n");
|
||||
"ExtendedDTraceProbes flag is not applicable for this configuration\n");
|
||||
return JNI_EINVAL;
|
||||
#endif // ndef SOLARIS
|
||||
#endif // defined(DTRACE_ENABLED)
|
||||
#ifdef ASSERT
|
||||
} else if (match_option(option, "-XX:+FullGCALot", &tail)) {
|
||||
FLAG_SET_CMDLINE(bool, FullGCALot, true);
|
||||
|
@ -677,7 +677,7 @@ class CommandLineFlags {
|
||||
notproduct(bool, WalkStackALot, false, \
|
||||
"trace stack (no print) at every exit from the runtime system") \
|
||||
\
|
||||
develop(bool, Debugging, false, \
|
||||
product(bool, Debugging, false, \
|
||||
"set when executing debug methods in debug.ccp " \
|
||||
"(to prevent triggering assertions)") \
|
||||
\
|
||||
|
@ -105,7 +105,9 @@
|
||||
#include "opto/runtime.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL(hotspot, vm__shutdown);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -547,8 +549,12 @@ void vm_exit(int code) {
|
||||
|
||||
void notify_vm_shutdown() {
|
||||
// For now, just a dtrace probe.
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hotspot, vm__shutdown);
|
||||
HS_DTRACE_WORKAROUND_TAIL_CALL_BUG();
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_VM_SHUTDOWN();
|
||||
#endif /* USDT2 */
|
||||
}
|
||||
|
||||
void vm_direct_exit(int code) {
|
||||
|
@ -68,16 +68,6 @@
|
||||
// Only bother with this argument setup if dtrace is available
|
||||
// TODO-FIXME: probes should not fire when caller is _blocked. assert() accordingly.
|
||||
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__notify,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__notifyAll,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__enter,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__entered,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__exit,
|
||||
jlong, uintptr_t, char*, int);
|
||||
|
||||
#define DTRACE_MONITOR_PROBE_COMMON(klassOop, thread) \
|
||||
char* bytes = NULL; \
|
||||
@ -89,6 +79,19 @@ HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__exit,
|
||||
len = klassname->utf8_length(); \
|
||||
}
|
||||
|
||||
#ifndef USDT2
|
||||
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__notify,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__notifyAll,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__enter,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__entered,
|
||||
jlong, uintptr_t, char*, int);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__exit,
|
||||
jlong, uintptr_t, char*, int);
|
||||
|
||||
#define DTRACE_MONITOR_WAIT_PROBE(monitor, klassOop, thread, millis) \
|
||||
{ \
|
||||
if (DTraceMonitorProbes) { \
|
||||
@ -107,6 +110,33 @@ HS_DTRACE_PROBE_DECL4(hotspot, monitor__contended__exit,
|
||||
} \
|
||||
}
|
||||
|
||||
#else /* USDT2 */
|
||||
|
||||
#define DTRACE_MONITOR_WAIT_PROBE(monitor, klassOop, thread, millis) \
|
||||
{ \
|
||||
if (DTraceMonitorProbes) { \
|
||||
DTRACE_MONITOR_PROBE_COMMON(klassOop, thread); \
|
||||
HOTSPOT_MONITOR_WAIT(jtid, \
|
||||
(monitor), bytes, len, (millis)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HOTSPOT_MONITOR_contended__enter HOTSPOT_MONITOR_CONTENDED_ENTER
|
||||
#define HOTSPOT_MONITOR_contended__entered HOTSPOT_MONITOR_CONTENDED_ENTERED
|
||||
#define HOTSPOT_MONITOR_contended__exit HOTSPOT_MONITOR_CONTENDED_EXIT
|
||||
#define HOTSPOT_MONITOR_notify HOTSPOT_MONITOR_NOTIFY
|
||||
#define HOTSPOT_MONITOR_notifyAll HOTSPOT_MONITOR_NOTIFYALL
|
||||
|
||||
#define DTRACE_MONITOR_PROBE(probe, monitor, klassOop, thread) \
|
||||
{ \
|
||||
if (DTraceMonitorProbes) { \
|
||||
DTRACE_MONITOR_PROBE_COMMON(klassOop, thread); \
|
||||
HOTSPOT_MONITOR_##probe(jtid, \
|
||||
(uintptr_t)(monitor), bytes, len); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* USDT2 */
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
#define DTRACE_MONITOR_WAIT_PROBE(klassOop, thread, millis, mon) {;}
|
||||
|
@ -1095,6 +1095,9 @@ bool os::set_boot_path(char fileSep, char pathSep) {
|
||||
"%/lib/jsse.jar:"
|
||||
"%/lib/jce.jar:"
|
||||
"%/lib/charsets.jar:"
|
||||
#ifdef __APPLE__
|
||||
"%/lib/JObjC.jar:"
|
||||
#endif
|
||||
"%/classes";
|
||||
char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);
|
||||
if (sysclasspath == NULL) return false;
|
||||
|
@ -184,6 +184,9 @@ class os: AllStatic {
|
||||
// Returns true if it worked, false if it didn't.
|
||||
static bool bind_to_processor(uint processor_id);
|
||||
|
||||
// Give a name to the current thread.
|
||||
static void set_native_thread_name(const char *name);
|
||||
|
||||
// Interface for stack banging (predetect possible stack overflow for
|
||||
// exception processing) There are guard pages, and above that shadow
|
||||
// pages for stack overflow checking.
|
||||
|
@ -148,11 +148,13 @@ void SharedRuntime::generate_ricochet_blob() {
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, object__alloc, Thread*, char*, int, size_t);
|
||||
HS_DTRACE_PROBE_DECL7(hotspot, method__entry, int,
|
||||
char*, int, char*, int, char*, int);
|
||||
HS_DTRACE_PROBE_DECL7(hotspot, method__return, int,
|
||||
char*, int, char*, int, char*, int);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
// Implementation of SharedRuntime
|
||||
|
||||
@ -659,12 +661,14 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc,
|
||||
int scope_depth = 0;
|
||||
if (!force_unwind) {
|
||||
int bci = sd->bci();
|
||||
bool recursive_exception = false;
|
||||
do {
|
||||
bool skip_scope_increment = false;
|
||||
// exception handler lookup
|
||||
KlassHandle ek (THREAD, exception->klass());
|
||||
handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
recursive_exception = true;
|
||||
// We threw an exception while trying to find the exception handler.
|
||||
// Transfer the new exception to the exception handle which will
|
||||
// be set into thread local storage, and do another lookup for an
|
||||
@ -680,6 +684,9 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc,
|
||||
skip_scope_increment = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
recursive_exception = false;
|
||||
}
|
||||
if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) {
|
||||
sd = sd->sender();
|
||||
if (sd != NULL) {
|
||||
@ -687,7 +694,7 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc,
|
||||
}
|
||||
++scope_depth;
|
||||
}
|
||||
} while (!top_frame_only && handler_bci < 0 && sd != NULL);
|
||||
} while (recursive_exception || (!top_frame_only && handler_bci < 0 && sd != NULL));
|
||||
}
|
||||
|
||||
// found handling method => lookup exception handler
|
||||
@ -954,8 +961,14 @@ int SharedRuntime::dtrace_object_alloc_base(Thread* thread, oopDesc* o) {
|
||||
Klass* klass = o->blueprint();
|
||||
int size = o->size();
|
||||
Symbol* name = klass->name();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE4(hotspot, object__alloc, get_java_tid(thread),
|
||||
name->bytes(), name->utf8_length(), size * HeapWordSize);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_OBJECT_ALLOC(
|
||||
get_java_tid(thread),
|
||||
(char *) name->bytes(), name->utf8_length(), size * HeapWordSize);
|
||||
#endif /* USDT2 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -965,10 +978,18 @@ JRT_LEAF(int, SharedRuntime::dtrace_method_entry(
|
||||
Symbol* kname = method->klass_name();
|
||||
Symbol* name = method->name();
|
||||
Symbol* sig = method->signature();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE7(hotspot, method__entry, get_java_tid(thread),
|
||||
kname->bytes(), kname->utf8_length(),
|
||||
name->bytes(), name->utf8_length(),
|
||||
sig->bytes(), sig->utf8_length());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_METHOD_ENTRY(
|
||||
get_java_tid(thread),
|
||||
(char *) kname->bytes(), kname->utf8_length(),
|
||||
(char *) name->bytes(), name->utf8_length(),
|
||||
(char *) sig->bytes(), sig->utf8_length());
|
||||
#endif /* USDT2 */
|
||||
return 0;
|
||||
JRT_END
|
||||
|
||||
@ -978,10 +999,18 @@ JRT_LEAF(int, SharedRuntime::dtrace_method_exit(
|
||||
Symbol* kname = method->klass_name();
|
||||
Symbol* name = method->name();
|
||||
Symbol* sig = method->signature();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE7(hotspot, method__return, get_java_tid(thread),
|
||||
kname->bytes(), kname->utf8_length(),
|
||||
name->bytes(), name->utf8_length(),
|
||||
sig->bytes(), sig->utf8_length());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_METHOD_RETURN(
|
||||
get_java_tid(thread),
|
||||
(char *) kname->bytes(), kname->utf8_length(),
|
||||
(char *) name->bytes(), name->utf8_length(),
|
||||
(char *) sig->bytes(), sig->utf8_length());
|
||||
#endif /* USDT2 */
|
||||
return 0;
|
||||
JRT_END
|
||||
|
||||
|
@ -77,11 +77,6 @@
|
||||
// Only bother with this argument setup if dtrace is available
|
||||
// TODO-FIXME: probes should not fire when caller is _blocked. assert() accordingly.
|
||||
|
||||
HS_DTRACE_PROBE_DECL5(hotspot, monitor__wait,
|
||||
jlong, uintptr_t, char*, int, long);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__waited,
|
||||
jlong, uintptr_t, char*, int);
|
||||
|
||||
#define DTRACE_MONITOR_PROBE_COMMON(klassOop, thread) \
|
||||
char* bytes = NULL; \
|
||||
int len = 0; \
|
||||
@ -92,6 +87,12 @@ HS_DTRACE_PROBE_DECL4(hotspot, monitor__waited,
|
||||
len = klassname->utf8_length(); \
|
||||
}
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL5(hotspot, monitor__wait,
|
||||
jlong, uintptr_t, char*, int, long);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, monitor__waited,
|
||||
jlong, uintptr_t, char*, int);
|
||||
|
||||
#define DTRACE_MONITOR_WAIT_PROBE(monitor, klassOop, thread, millis) \
|
||||
{ \
|
||||
if (DTraceMonitorProbes) { \
|
||||
@ -110,6 +111,29 @@ HS_DTRACE_PROBE_DECL4(hotspot, monitor__waited,
|
||||
} \
|
||||
}
|
||||
|
||||
#else /* USDT2 */
|
||||
|
||||
#define DTRACE_MONITOR_WAIT_PROBE(monitor, klassOop, thread, millis) \
|
||||
{ \
|
||||
if (DTraceMonitorProbes) { \
|
||||
DTRACE_MONITOR_PROBE_COMMON(klassOop, thread); \
|
||||
HOTSPOT_MONITOR_WAIT(jtid, \
|
||||
(uintptr_t)(monitor), bytes, len, (millis)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HOTSPOT_MONITOR_PROBE_waited HOTSPOT_MONITOR_PROBE_WAITED
|
||||
|
||||
#define DTRACE_MONITOR_PROBE(probe, monitor, klassOop, thread) \
|
||||
{ \
|
||||
if (DTraceMonitorProbes) { \
|
||||
DTRACE_MONITOR_PROBE_COMMON(klassOop, thread); \
|
||||
HOTSPOT_MONITOR_PROBE_##probe(jtid, /* probe = waited */ \
|
||||
(uintptr_t)(monitor), bytes, len); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* USDT2 */
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
#define DTRACE_MONITOR_WAIT_PROBE(klassOop, thread, millis, mon) {;}
|
||||
|
@ -110,6 +110,7 @@
|
||||
|
||||
// Only bother with this argument setup if dtrace is available
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL(hotspot, vm__init__begin);
|
||||
HS_DTRACE_PROBE_DECL(hotspot, vm__init__end);
|
||||
HS_DTRACE_PROBE_DECL5(hotspot, thread__start, char*, intptr_t,
|
||||
@ -130,6 +131,26 @@ HS_DTRACE_PROBE_DECL5(hotspot, thread__stop, char*, intptr_t,
|
||||
java_lang_Thread::is_daemon((javathread)->threadObj())); \
|
||||
}
|
||||
|
||||
#else /* USDT2 */
|
||||
|
||||
#define HOTSPOT_THREAD_PROBE_start HOTSPOT_THREAD_PROBE_START
|
||||
#define HOTSPOT_THREAD_PROBE_stop HOTSPOT_THREAD_PROBE_STOP
|
||||
|
||||
#define DTRACE_THREAD_PROBE(probe, javathread) \
|
||||
{ \
|
||||
ResourceMark rm(this); \
|
||||
int len = 0; \
|
||||
const char* name = (javathread)->get_thread_name(); \
|
||||
len = strlen(name); \
|
||||
HOTSPOT_THREAD_PROBE_##probe( /* probe = start, stop */ \
|
||||
(char *) name, len, \
|
||||
java_lang_Thread::thread_id((javathread)->threadObj()), \
|
||||
(uintptr_t) (javathread)->osthread()->thread_id(), \
|
||||
java_lang_Thread::is_daemon((javathread)->threadObj())); \
|
||||
}
|
||||
|
||||
#endif /* USDT2 */
|
||||
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
#define DTRACE_THREAD_PROBE(probe, javathread)
|
||||
@ -1328,7 +1349,7 @@ SATBMarkQueueSet JavaThread::_satb_mark_queue_set;
|
||||
DirtyCardQueueSet JavaThread::_dirty_card_queue_set;
|
||||
#endif // !SERIALGC
|
||||
|
||||
JavaThread::JavaThread(bool is_attaching) :
|
||||
JavaThread::JavaThread(bool is_attaching_via_jni) :
|
||||
Thread()
|
||||
#ifndef SERIALGC
|
||||
, _satb_mark_queue(&_satb_mark_queue_set),
|
||||
@ -1336,7 +1357,11 @@ JavaThread::JavaThread(bool is_attaching) :
|
||||
#endif // !SERIALGC
|
||||
{
|
||||
initialize();
|
||||
_is_attaching = is_attaching;
|
||||
if (is_attaching_via_jni) {
|
||||
_jni_attach_state = _attaching_via_jni;
|
||||
} else {
|
||||
_jni_attach_state = _not_attaching_via_jni;
|
||||
}
|
||||
assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor");
|
||||
}
|
||||
|
||||
@ -1392,7 +1417,7 @@ JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
|
||||
tty->print_cr("creating thread %p", this);
|
||||
}
|
||||
initialize();
|
||||
_is_attaching = false;
|
||||
_jni_attach_state = _not_attaching_via_jni;
|
||||
set_entry_point(entry_point);
|
||||
// Create the native thread itself.
|
||||
// %note runtime_23
|
||||
@ -1504,6 +1529,10 @@ void JavaThread::thread_main_inner() {
|
||||
// Note: Due to JVM_StopThread we can have pending exceptions already!
|
||||
if (!this->has_pending_exception() &&
|
||||
!java_lang_Thread::is_stillborn(this->threadObj())) {
|
||||
{
|
||||
ResourceMark rm(this);
|
||||
this->set_native_thread_name(this->get_thread_name());
|
||||
}
|
||||
HandleMark hm(this);
|
||||
this->entry_point()(this, this);
|
||||
}
|
||||
@ -2683,7 +2712,7 @@ const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
|
||||
name_str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length(), buf, buflen);
|
||||
}
|
||||
}
|
||||
else if (is_attaching()) { // workaround for 6412693 - see 6404306
|
||||
else if (is_attaching_via_jni()) { // workaround for 6412693 - see 6404306
|
||||
name_str = "<no-name - thread is attaching>";
|
||||
}
|
||||
else {
|
||||
@ -3079,7 +3108,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
os::pause();
|
||||
}
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hotspot, vm__init__begin);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_VM_INIT_BEGIN();
|
||||
#endif /* USDT2 */
|
||||
|
||||
// Record VM creation timing statistics
|
||||
TraceVmCreationTime create_vm_timer;
|
||||
@ -3334,7 +3367,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
// debug stuff, that does not work until all basic classes have been initialized.
|
||||
set_init_completed();
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE(hotspot, vm__init__end);
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_VM_INIT_END();
|
||||
#endif /* USDT2 */
|
||||
|
||||
// record VM initialization completion time
|
||||
Management::record_vm_init_completed();
|
||||
|
@ -309,6 +309,11 @@ class Thread: public ThreadShadow {
|
||||
static void interrupt(Thread* thr);
|
||||
static bool is_interrupted(Thread* thr, bool clear_interrupted);
|
||||
|
||||
void set_native_thread_name(const char *name) {
|
||||
assert(Thread::current() == this, "set_native_thread_name can only be called on the current thread");
|
||||
os::set_native_thread_name(name);
|
||||
}
|
||||
|
||||
ObjectMonitor** omInUseList_addr() { return (ObjectMonitor **)&omInUseList; }
|
||||
Monitor* SR_lock() const { return _SR_lock; }
|
||||
|
||||
@ -818,10 +823,17 @@ class JavaThread: public Thread {
|
||||
bool _do_not_unlock_if_synchronized; // Do not unlock the receiver of a synchronized method (since it was
|
||||
// never locked) when throwing an exception. Used by interpreter only.
|
||||
|
||||
// Flag to mark a JNI thread in the process of attaching - See CR 6404306
|
||||
// This flag is never set true other than at construction, and in that case
|
||||
// is shortly thereafter set false
|
||||
volatile bool _is_attaching;
|
||||
// JNI attach states:
|
||||
enum JNIAttachStates {
|
||||
_not_attaching_via_jni = 1, // thread is not attaching via JNI
|
||||
_attaching_via_jni, // thread is attaching via JNI
|
||||
_attached_via_jni // thread has attached via JNI
|
||||
};
|
||||
|
||||
// A regular JavaThread's _jni_attach_state is _not_attaching_via_jni.
|
||||
// A native thread that is attaching via JNI starts with a value
|
||||
// of _attaching_via_jni and transitions to _attached_via_jni.
|
||||
volatile JNIAttachStates _jni_attach_state;
|
||||
|
||||
public:
|
||||
// State of the stack guard pages for this thread.
|
||||
@ -889,7 +901,7 @@ class JavaThread: public Thread {
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
JavaThread(bool is_attaching = false); // for main thread and JNI attached threads
|
||||
JavaThread(bool is_attaching_via_jni = false); // for main thread and JNI attached threads
|
||||
JavaThread(ThreadFunction entry_point, size_t stack_size = 0);
|
||||
~JavaThread();
|
||||
|
||||
@ -1641,8 +1653,9 @@ public:
|
||||
void set_cached_monitor_info(GrowableArray<MonitorInfo*>* info) { _cached_monitor_info = info; }
|
||||
|
||||
// clearing/querying jni attach status
|
||||
bool is_attaching() const { return _is_attaching; }
|
||||
void set_attached() { _is_attaching = false; OrderAccess::fence(); }
|
||||
bool is_attaching_via_jni() const { return _jni_attach_state == _attaching_via_jni; }
|
||||
bool has_attached_via_jni() const { return is_attaching_via_jni() || _jni_attach_state == _attached_via_jni; }
|
||||
void set_done_attaching_via_jni() { _jni_attach_state = _attached_via_jni; OrderAccess::fence(); }
|
||||
private:
|
||||
// This field is used to determine if a thread has claimed
|
||||
// a par_id: it is -1 if the thread has not claimed a par_id;
|
||||
|
@ -50,9 +50,11 @@
|
||||
# include "thread_bsd.inline.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
|
||||
HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
|
||||
HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int);
|
||||
#endif /* !USDT2 */
|
||||
|
||||
// Dummy VM operation to act as first element in our circular double-linked list
|
||||
class VM_Dummy: public VM_Operation {
|
||||
@ -162,8 +164,14 @@ void VMOperationQueue::drain_list_oops_do(OopClosure* f) {
|
||||
// High-level interface
|
||||
bool VMOperationQueue::add(VM_Operation *op) {
|
||||
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()),
|
||||
op->evaluation_mode());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_VMOPS_REQUEST(
|
||||
(char *) op->name(), strlen(op->name()),
|
||||
op->evaluation_mode());
|
||||
#endif /* USDT2 */
|
||||
|
||||
// Encapsulates VM queue policy. Currently, that
|
||||
// only involves putting them on the right list
|
||||
@ -360,11 +368,23 @@ void VMThread::evaluate_operation(VM_Operation* op) {
|
||||
|
||||
{
|
||||
PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()),
|
||||
op->evaluation_mode());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_VMOPS_BEGIN(
|
||||
(char *) op->name(), strlen(op->name()),
|
||||
op->evaluation_mode());
|
||||
#endif /* USDT2 */
|
||||
op->evaluate();
|
||||
#ifndef USDT2
|
||||
HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
|
||||
op->evaluation_mode());
|
||||
#else /* USDT2 */
|
||||
HOTSPOT_VMOPS_END(
|
||||
(char *) op->name(), strlen(op->name()),
|
||||
op->evaluation_mode());
|
||||
#endif /* USDT2 */
|
||||
}
|
||||
|
||||
// Last access of info in _cur_vm_operation!
|
||||
|
@ -128,7 +128,7 @@ void Abstract_VM_Version::initialize() {
|
||||
#ifndef HOTSPOT_VM_DISTRO
|
||||
#error HOTSPOT_VM_DISTRO must be defined
|
||||
#endif
|
||||
#define VMNAME HOTSPOT_VM_DISTRO " " VMLP VMTYPE " VM"
|
||||
#define VMNAME HOTSPOT_VM_DISTRO " " VMLP EMBEDDED_ONLY("Embedded ") VMTYPE " VM"
|
||||
|
||||
const char* Abstract_VM_Version::vm_name() {
|
||||
return VMNAME;
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
// Only bother with this argument setup if dtrace is available
|
||||
|
||||
#ifndef USDT2
|
||||
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, class__loaded, char*, int, oop, bool);
|
||||
HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool);
|
||||
|
||||
@ -52,6 +54,24 @@ HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool);
|
||||
data, len, (clss)->class_loader(), (shared)); \
|
||||
}
|
||||
|
||||
#else /* USDT2 */
|
||||
|
||||
#define HOTSPOT_CLASS_unloaded HOTSPOT_CLASS_UNLOADED
|
||||
#define HOTSPOT_CLASS_loaded HOTSPOT_CLASS_LOADED
|
||||
#define DTRACE_CLASSLOAD_PROBE(type, clss, shared) \
|
||||
{ \
|
||||
char* data = NULL; \
|
||||
int len = 0; \
|
||||
Symbol* name = (clss)->name(); \
|
||||
if (name != NULL) { \
|
||||
data = (char*)name->bytes(); \
|
||||
len = name->utf8_length(); \
|
||||
} \
|
||||
HOTSPOT_CLASS_##type( /* type = unloaded, loaded */ \
|
||||
data, len, (clss)->class_loader(), (shared)); \
|
||||
}
|
||||
|
||||
#endif /* USDT2 */
|
||||
#else // ndef DTRACE_ENABLED
|
||||
|
||||
#define DTRACE_CLASSLOAD_PROBE(type, clss, shared)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user