aboutsummaryrefslogtreecommitdiff
path: root/patches/hotspot
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2013-05-08 12:52:58 +0200
committerGuido Günther <agx@sigxcpu.org>2013-05-08 12:52:58 +0200
commit9a8e56049ebf9f0878c7fe3efc0921df8aa6a0ba (patch)
tree7d61a00fa8d6ec4667663370cc42b04be03ec569 /patches/hotspot
Imported Upstream version 7u21-2.3.9upstream/7u21-2.3.9upstream
Diffstat (limited to 'patches/hotspot')
-rw-r--r--patches/hotspot/default/revert-7017193.patch138
-rw-r--r--patches/hotspot/zero/6924259-string_offset.patch916
-rw-r--r--patches/hotspot/zero/7089790-bsd_port.patch28881
-rw-r--r--patches/hotspot/zero/7098194-macosx_port.patch11389
-rw-r--r--patches/hotspot/zero/7116189-setnativethreadname.patch67
-rw-r--r--patches/hotspot/zero/7175133-string_offset.patch48
-rw-r--r--patches/hotspot/zero/revert-7017193.patch136
-rw-r--r--patches/hotspot/zero/revert_arm_debug.patch55
8 files changed, 41630 insertions, 0 deletions
diff --git a/patches/hotspot/default/revert-7017193.patch b/patches/hotspot/default/revert-7017193.patch
new file mode 100644
index 0000000..7518362
--- /dev/null
+++ b/patches/hotspot/default/revert-7017193.patch
@@ -0,0 +1,138 @@
+diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp
+--- openjdk/hotspot/src/os/linux/vm/os_linux.cpp
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+@@ -2763,39 +2763,47 @@
+ // writing thread stacks don't use growable mappings (i.e. those
+ // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
+ // only applies to the main thread.
+-
+-static
+-bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) {
+-
+- char buf[128];
+- int fd, sz;
+-
+- if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) {
++static bool
++get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
++{
++ FILE *f = fopen("/proc/self/maps", "r");
++ if (f == NULL)
+ return false;
+- }
+-
+- const char kw[] = "[stack]";
+- const int kwlen = sizeof(kw)-1;
+-
+- // Address part of /proc/self/maps couldn't be more than 128 bytes
+- while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) {
+- if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) {
+- // Extract addresses
+- if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+- uintptr_t sp = (uintptr_t) __builtin_frame_address(0);
+- if (sp >= *bottom && sp <= *top) {
+- ::close(fd);
+- return true;
+- }
++
++ while (!feof(f)) {
++ size_t dummy;
++ char *str = NULL;
++ ssize_t len = getline(&str, &dummy, f);
++ if (len == -1) {
++ fclose(f);
++ if (str != NULL)
++ free(str);
++ return false;
++ }
++
++ if (len > 0 && str[len-1] == '\n') {
++ str[len-1] = 0;
++ len--;
++ }
++
++ static const char *stack_str = "[stack]";
++ if (len > (ssize_t)strlen(stack_str)
++ && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
++ if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
++ uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
++ if (sp >= *bottom && sp <= *top) {
++ free(str);
++ fclose(f);
++ return true;
+ }
+- }
+- }
+-
+- ::close(fd);
++ }
++ }
++ free(str);
++ }
++ fclose(f);
+ return false;
+ }
+
+-
+ // If the (growable) stack mapping already extends beyond the point
+ // where we're going to put our guard pages, truncate the mapping at
+ // that point by munmap()ping it. This ensures that when we later
+diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp
+--- openjdk/hotspot/src/share/vm/runtime/os.cpp
++++ openjdk/hotspot/src/share/vm/runtime/os.cpp
+@@ -1331,41 +1331,3 @@
+ }
+ return result;
+ }
+-
+-// Read file line by line, if line is longer than bsize,
+-// skip rest of line.
+-int os::get_line_chars(int fd, char* buf, const size_t bsize){
+- size_t sz, i = 0;
+-
+- // read until EOF, EOL or buf is full
+- while ((sz = (int) read(fd, &buf[i], 1)) == 1 && i < (bsize-2) && buf[i] != '\n') {
+- ++i;
+- }
+-
+- if (buf[i] == '\n') {
+- // EOL reached so ignore EOL character and return
+-
+- buf[i] = 0;
+- return (int) i;
+- }
+-
+- buf[i+1] = 0;
+-
+- if (sz != 1) {
+- // EOF reached. if we read chars before EOF return them and
+- // return EOF on next call otherwise return EOF
+-
+- return (i == 0) ? -1 : (int) i;
+- }
+-
+- // line is longer than size of buf, skip to EOL
+- char ch;
+- while (read(fd, &ch, 1) == 1 && ch != '\n') {
+- // Do nothing
+- }
+-
+- // return initial part of line that fits in buf.
+- // If we reached EOF, it will be returned on next call.
+-
+- return (int) i;
+-}
+diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp
+--- openjdk/hotspot/src/share/vm/runtime/os.hpp
++++ openjdk/hotspot/src/share/vm/runtime/os.hpp
+@@ -672,10 +672,6 @@
+ // Hook for os specific jvm options that we don't want to abort on seeing
+ static bool obsolete_option(const JavaVMOption *option);
+
+- // Read file line by line. If line is longer than bsize,
+- // rest of line is skipped. Returns number of bytes read or -1 on EOF
+- static int get_line_chars(int fd, char *buf, const size_t bsize);
+-
+ // Extensions
+ #include "runtime/os_ext.hpp"
+
diff --git a/patches/hotspot/zero/6924259-string_offset.patch b/patches/hotspot/zero/6924259-string_offset.patch
new file mode 100644
index 0000000..490825b
--- /dev/null
+++ b/patches/hotspot/zero/6924259-string_offset.patch
@@ -0,0 +1,916 @@
+diff -Nru openjdk.orig/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp openjdk/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
+--- openjdk.orig/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp 2013-01-16 00:42:59.059088003 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -238,9 +238,12 @@
+
+ Register result = dst->as_register();
+ {
+- // Get a pointer to the first character of string0 in tmp0 and get string0.count in str0
+- // Get a pointer to the first character of string1 in tmp1 and get string1.count in str1
+- // Also, get string0.count-string1.count in o7 and get the condition code set
++ // Get a pointer to the first character of string0 in tmp0
++ // and get string0.length() in str0
++ // Get a pointer to the first character of string1 in tmp1
++ // and get string1.length() in str1
++ // Also, get string0.length()-string1.length() in
++ // o7 and get the condition code set
+ // Note: some instructions have been hoisted for better instruction scheduling
+
+ Register tmp0 = L0;
+@@ -248,27 +251,40 @@
+ Register tmp2 = L2;
+
+ int value_offset = java_lang_String:: value_offset_in_bytes(); // char array
+- int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
+- int count_offset = java_lang_String:: count_offset_in_bytes();
+-
+- __ load_heap_oop(str0, value_offset, tmp0);
+- __ ld(str0, offset_offset, tmp2);
+- __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
+- __ ld(str0, count_offset, str0);
+- __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
++ if (java_lang_String::has_offset_field()) {
++ int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
++ int count_offset = java_lang_String:: count_offset_in_bytes();
++ __ load_heap_oop(str0, value_offset, tmp0);
++ __ ld(str0, offset_offset, tmp2);
++ __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
++ __ ld(str0, count_offset, str0);
++ __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
++ } else {
++ __ load_heap_oop(str0, value_offset, tmp1);
++ __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
++ __ ld(tmp1, arrayOopDesc::length_offset_in_bytes(), str0);
++ }
+
+ // str1 may be null
+ add_debug_info_for_null_check_here(info);
+
+- __ load_heap_oop(str1, value_offset, tmp1);
+- __ add(tmp0, tmp2, tmp0);
+-
+- __ ld(str1, offset_offset, tmp2);
+- __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
+- __ ld(str1, count_offset, str1);
+- __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
++ if (java_lang_String::has_offset_field()) {
++ int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
++ int count_offset = java_lang_String:: count_offset_in_bytes();
++ __ load_heap_oop(str1, value_offset, tmp1);
++ __ add(tmp0, tmp2, tmp0);
++
++ __ ld(str1, offset_offset, tmp2);
++ __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
++ __ ld(str1, count_offset, str1);
++ __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
++ __ add(tmp1, tmp2, tmp1);
++ } else {
++ __ load_heap_oop(str1, value_offset, tmp2);
++ __ add(tmp2, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
++ __ ld(tmp2, arrayOopDesc::length_offset_in_bytes(), str1);
++ }
+ __ subcc(str0, str1, O7);
+- __ add(tmp1, tmp2, tmp1);
+ }
+
+ {
+@@ -302,7 +318,7 @@
+ // Shift base0 and base1 to the end of the arrays, negate limit
+ __ add(base0, limit, base0);
+ __ add(base1, limit, base1);
+- __ neg(limit); // limit = -min{string0.count, strin1.count}
++ __ neg(limit); // limit = -min{string0.length(), string1.length()}
+
+ __ lduh(base0, limit, chr0);
+ __ bind(Lloop);
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2013-01-16 00:41:43.257866830 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2013-01-16 00:42:59.059088003 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -506,19 +506,28 @@
+
+ // Get addresses of first characters from both Strings
+ __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
+- __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
+- __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
+-
++ if (java_lang_String::has_offset_field()) {
++ __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
++ __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
++ __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
++ } else {
++ __ movl (rax, Address(rsi, arrayOopDesc::length_offset_in_bytes()));
++ __ lea (rsi, Address(rsi, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
++ }
+
+ // rbx, may be NULL
+ add_debug_info_for_null_check_here(info);
+ __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
+- __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
+- __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
++ if (java_lang_String::has_offset_field()) {
++ __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
++ __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
++ __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
++ } else {
++ __ movl (rbx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
++ __ lea (rdi, Address(rdi, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
++ }
+
+ // compute minimum length (in rax) and difference of lengths (on top of stack)
+- __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
+- __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
+ __ mov (rcx, rbx);
+ __ subptr(rbx, rax); // subtract lengths
+ __ push (rbx); // result
+diff -Nru openjdk.orig/hotspot/src/share/vm/classfile/javaClasses.cpp openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp
+--- openjdk.orig/hotspot/src/share/vm/classfile/javaClasses.cpp 2013-01-16 00:41:43.273867087 +0000
++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp 2013-01-16 00:42:59.071088195 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -144,7 +144,27 @@
+ }
+
+
++int java_lang_String::value_offset = 0;
++int java_lang_String::offset_offset = 0;
++int java_lang_String::count_offset = 0;
++int java_lang_String::hash_offset = 0;
++
++bool java_lang_String::initialized = false;
++
++void java_lang_String::compute_offsets() {
++ assert(!initialized, "offsets should be initialized only once");
++
++ klassOop k = SystemDictionary::String_klass();
++ compute_offset(value_offset, k, vmSymbols::value_name(), vmSymbols::char_array_signature());
++ compute_optional_offset(offset_offset, k, vmSymbols::offset_name(), vmSymbols::int_signature());
++ compute_optional_offset(count_offset, k, vmSymbols::count_name(), vmSymbols::int_signature());
++ compute_optional_offset(hash_offset, k, vmSymbols::hash_name(), vmSymbols::int_signature());
++
++ initialized = true;
++}
++
+ Handle java_lang_String::basic_create(int length, bool tenured, TRAPS) {
++ assert(initialized, "Must be initialized");
+ // Create the String object first, so there's a chance that the String
+ // and the char array it points to end up in the same cache line.
+ oop obj;
+@@ -2837,10 +2857,6 @@
+
+
+
+-int java_lang_String::value_offset;
+-int java_lang_String::offset_offset;
+-int java_lang_String::count_offset;
+-int java_lang_String::hash_offset;
+ int java_lang_Class::_klass_offset;
+ int java_lang_Class::_array_klass_offset;
+ int java_lang_Class::_resolved_constructor_offset;
+@@ -3000,12 +3016,6 @@
+ const int x = heapOopSize;
+ const int header = instanceOopDesc::base_offset_in_bytes();
+
+- // Do the String Class
+- java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header;
+- java_lang_String::offset_offset = java_lang_String::hc_offset_offset * x + header;
+- java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint);
+- java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint);
+-
+ // Throwable Class
+ java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header;
+ java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
+@@ -3200,9 +3210,13 @@
+ // java.lang.String
+
+ CHECK_OFFSET("java/lang/String", java_lang_String, value, "[C");
+- CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I");
+- CHECK_OFFSET("java/lang/String", java_lang_String, count, "I");
+- CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
++ if (java_lang_String::has_offset_field()) {
++ CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I");
++ CHECK_OFFSET("java/lang/String", java_lang_String, count, "I");
++ }
++ if (java_lang_String::has_hash_field()) {
++ CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
++ }
+
+ // java.lang.Class
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/classfile/javaClasses.hpp openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp
+--- openjdk.orig/hotspot/src/share/vm/classfile/javaClasses.hpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp 2013-01-16 00:42:59.071088195 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -52,26 +52,36 @@
+
+ class java_lang_String : AllStatic {
+ private:
+- enum {
+- hc_value_offset = 0,
+- hc_offset_offset = 1
+- //hc_count_offset = 2 -- not a word-scaled offset
+- //hc_hash_offset = 3 -- not a word-scaled offset
+- };
+-
+ static int value_offset;
+ static int offset_offset;
+ static int count_offset;
+ static int hash_offset;
+
++ static bool initialized;
++
+ static Handle basic_create(int length, bool tenured, TRAPS);
+ static Handle basic_create_from_unicode(jchar* unicode, int length, bool tenured, TRAPS);
+
+- static void set_value( oop string, typeArrayOop buffer) { string->obj_field_put(value_offset, (oop)buffer); }
+- static void set_offset(oop string, int offset) { string->int_field_put(offset_offset, offset); }
+- static void set_count( oop string, int count) { string->int_field_put(count_offset, count); }
++ static void set_value( oop string, typeArrayOop buffer) {
++ assert(initialized, "Must be initialized");
++ string->obj_field_put(value_offset, (oop)buffer);
++ }
++ static void set_offset(oop string, int offset) {
++ assert(initialized, "Must be initialized");
++ if (offset_offset > 0) {
++ string->int_field_put(offset_offset, offset);
++ }
++ }
++ static void set_count( oop string, int count) {
++ assert(initialized, "Must be initialized");
++ if (count_offset > 0) {
++ string->int_field_put(count_offset, count);
++ }
++ }
+
+ public:
++ static void compute_offsets();
++
+ // Instance creation
+ static Handle create_from_unicode(jchar* unicode, int len, TRAPS);
+ static Handle create_tenured_from_unicode(jchar* unicode, int len, TRAPS);
+@@ -82,23 +92,61 @@
+ static Handle create_from_platform_dependent_str(const char* str, TRAPS);
+ static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
+
+- static int value_offset_in_bytes() { return value_offset; }
+- static int count_offset_in_bytes() { return count_offset; }
+- static int offset_offset_in_bytes() { return offset_offset; }
+- static int hash_offset_in_bytes() { return hash_offset; }
++ static bool has_offset_field() {
++ assert(initialized, "Must be initialized");
++ return (offset_offset > 0);
++ }
++
++ static bool has_count_field() {
++ assert(initialized, "Must be initialized");
++ return (count_offset > 0);
++ }
++
++ static bool has_hash_field() {
++ assert(initialized, "Must be initialized");
++ return (hash_offset > 0);
++ }
++
++ static int value_offset_in_bytes() {
++ assert(initialized && (value_offset > 0), "Must be initialized");
++ return value_offset;
++ }
++ static int count_offset_in_bytes() {
++ assert(initialized && (count_offset > 0), "Must be initialized");
++ return count_offset;
++ }
++ static int offset_offset_in_bytes() {
++ assert(initialized && (offset_offset > 0), "Must be initialized");
++ return offset_offset;
++ }
++ static int hash_offset_in_bytes() {
++ assert(initialized && (hash_offset > 0), "Must be initialized");
++ return hash_offset;
++ }
+
+ // Accessors
+ static typeArrayOop value(oop java_string) {
++ assert(initialized && (value_offset > 0), "Must be initialized");
+ assert(is_instance(java_string), "must be java_string");
+ return (typeArrayOop) java_string->obj_field(value_offset);
+ }
+ static int offset(oop java_string) {
++ assert(initialized, "Must be initialized");
+ assert(is_instance(java_string), "must be java_string");
+- return java_string->int_field(offset_offset);
++ if (offset_offset > 0) {
++ return java_string->int_field(offset_offset);
++ } else {
++ return 0;
++ }
+ }
+ static int length(oop java_string) {
++ assert(initialized, "Must be initialized");
+ assert(is_instance(java_string), "must be java_string");
+- return java_string->int_field(count_offset);
++ if (count_offset > 0) {
++ return java_string->int_field(count_offset);
++ } else {
++ return ((typeArrayOop)java_string->obj_field(value_offset))->length();
++ }
+ }
+ static int utf8_length(oop java_string);
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/classfile/systemDictionary.cpp openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp
+--- openjdk.orig/hotspot/src/share/vm/classfile/systemDictionary.cpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp 2013-01-16 00:42:59.075088258 +0000
+@@ -1953,6 +1953,9 @@
+ // first do Object, String, Class
+ initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
+
++ // Calculate offsets for String and Class classes since they are loaded and
++ // can be used after this point.
++ java_lang_String::compute_offsets();
+ java_lang_Class::compute_offsets();
+
+ // Fixup mirrors for classes loaded before java.lang.Class.
+diff -Nru openjdk.orig/hotspot/src/share/vm/classfile/vmSymbols.hpp openjdk/hotspot/src/share/vm/classfile/vmSymbols.hpp
+--- openjdk.orig/hotspot/src/share/vm/classfile/vmSymbols.hpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/classfile/vmSymbols.hpp 2013-01-16 00:42:59.083088388 +0000
+@@ -337,6 +337,9 @@
+ template(park_event_name, "nativeParkEventPointer") \
+ template(cache_field_name, "cache") \
+ template(value_name, "value") \
++ template(offset_name, "offset") \
++ template(count_name, "count") \
++ template(hash_name, "hash") \
+ template(frontCacheEnabled_name, "frontCacheEnabled") \
+ template(stringCacheEnabled_name, "stringCacheEnabled") \
+ template(numberOfLeadingZeros_name, "numberOfLeadingZeros") \
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/dump.cpp openjdk/hotspot/src/share/vm/memory/dump.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/dump.cpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/memory/dump.cpp 2013-01-16 00:43:46.135846474 +0000
+@@ -78,8 +78,8 @@
+ void do_oop(oop* p) {
+ if (p != NULL) {
+ oop obj = *p;
+- if (obj->klass() == SystemDictionary::String_klass()) {
+-
++ if (obj->klass() == SystemDictionary::String_klass() &&
++ java_lang_String::has_hash_field()) {
+ int hash = java_lang_String::to_hash(obj);
+ obj->int_field_put(hash_offset, hash);
+ }
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/graphKit.cpp openjdk/hotspot/src/share/vm/opto/graphKit.cpp
+--- openjdk.orig/hotspot/src/share/vm/opto/graphKit.cpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/graphKit.cpp 2013-01-16 00:42:59.091088517 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -3730,3 +3730,81 @@
+ final_sync(ideal);
+ }
+ #undef __
++
++
++
++Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
++ if (java_lang_String::has_offset_field()) {
++ int offset_offset = java_lang_String::offset_offset_in_bytes();
++ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
++ false, NULL, 0);
++ const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
++ int offset_field_idx = C->get_alias_index(offset_field_type);
++ return make_load(ctrl,
++ basic_plus_adr(str, str, offset_offset),
++ TypeInt::INT, T_INT, offset_field_idx);
++ } else {
++ return intcon(0);
++ }
++}
++
++Node* GraphKit::load_String_length(Node* ctrl, Node* str) {
++ if (java_lang_String::has_count_field()) {
++ int count_offset = java_lang_String::count_offset_in_bytes();
++ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
++ false, NULL, 0);
++ const TypePtr* count_field_type = string_type->add_offset(count_offset);
++ int count_field_idx = C->get_alias_index(count_field_type);
++ return make_load(ctrl,
++ basic_plus_adr(str, str, count_offset),
++ TypeInt::INT, T_INT, count_field_idx);
++ } else {
++ return load_array_length(load_String_value(ctrl, str));
++ }
++}
++
++Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
++ int value_offset = java_lang_String::value_offset_in_bytes();
++ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
++ false, NULL, 0);
++ const TypePtr* value_field_type = string_type->add_offset(value_offset);
++ const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
++ TypeAry::make(TypeInt::CHAR,TypeInt::POS),
++ ciTypeArrayKlass::make(T_CHAR), true, 0);
++ int value_field_idx = C->get_alias_index(value_field_type);
++ return make_load(ctrl, basic_plus_adr(str, str, value_offset),
++ value_type, T_OBJECT, value_field_idx);
++}
++
++void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
++ int offset_offset = java_lang_String::offset_offset_in_bytes();
++ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
++ false, NULL, 0);
++ const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
++ int offset_field_idx = C->get_alias_index(offset_field_type);
++ store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
++ value, T_INT, offset_field_idx);
++}
++
++void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
++ int value_offset = java_lang_String::value_offset_in_bytes();
++ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
++ false, NULL, 0);
++ const TypePtr* value_field_type = string_type->add_offset(value_offset);
++ const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
++ TypeAry::make(TypeInt::CHAR,TypeInt::POS),
++ ciTypeArrayKlass::make(T_CHAR), true, 0);
++ int value_field_idx = C->get_alias_index(value_field_type);
++ store_to_memory(ctrl, basic_plus_adr(str, value_offset),
++ value, T_OBJECT, value_field_idx);
++}
++
++void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
++ int count_offset = java_lang_String::count_offset_in_bytes();
++ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
++ false, NULL, 0);
++ const TypePtr* count_field_type = string_type->add_offset(count_offset);
++ int count_field_idx = C->get_alias_index(count_field_type);
++ store_to_memory(ctrl, basic_plus_adr(str, count_offset),
++ value, T_INT, count_field_idx);
++}
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/graphKit.hpp openjdk/hotspot/src/share/vm/opto/graphKit.hpp
+--- openjdk.orig/hotspot/src/share/vm/opto/graphKit.hpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/graphKit.hpp 2013-01-16 00:42:59.095088581 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -781,6 +781,14 @@
+ Node* new_array(Node* klass_node, Node* count_val, int nargs,
+ Node* *return_size_val = NULL);
+
++ // java.lang.String helpers
++ Node* load_String_offset(Node* ctrl, Node* str);
++ Node* load_String_length(Node* ctrl, Node* str);
++ Node* load_String_value(Node* ctrl, Node* str);
++ void store_String_offset(Node* ctrl, Node* str, Node* value);
++ void store_String_length(Node* ctrl, Node* str, Node* value);
++ void store_String_value(Node* ctrl, Node* str, Node* value);
++
+ // Handy for making control flow
+ IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) {
+ IfNode* iff = new (C, 2) IfNode(ctrl, tst, prob, cnt);// New IfNode's
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/library_call.cpp openjdk/hotspot/src/share/vm/opto/library_call.cpp
+--- openjdk.orig/hotspot/src/share/vm/opto/library_call.cpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/library_call.cpp 2013-01-16 00:42:59.095088581 +0000
+@@ -147,7 +147,8 @@
+ return generate_method_call(method_id, true, false);
+ }
+
+- Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2);
++ Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
++ Node* make_string_method_node(int opcode, Node* str1, Node* str2);
+ bool inline_string_compareTo();
+ bool inline_string_indexOf();
+ Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
+@@ -844,48 +845,76 @@
+
+
+ //------------------------------make_string_method_node------------------------
+-// Helper method for String intrinsic finctions.
+-Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) {
+- const int value_offset = java_lang_String::value_offset_in_bytes();
+- const int count_offset = java_lang_String::count_offset_in_bytes();
+- const int offset_offset = java_lang_String::offset_offset_in_bytes();
+-
++// Helper method for String intrinsic functions. This version is called
++// with str1 and str2 pointing to String object nodes.
++//
++Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* str2) {
+ Node* no_ctrl = NULL;
+
+- ciInstanceKlass* klass = env()->String_klass();
+- const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
+-
+- const TypeAryPtr* value_type =
+- TypeAryPtr::make(TypePtr::NotNull,
+- TypeAry::make(TypeInt::CHAR,TypeInt::POS),
+- ciTypeArrayKlass::make(T_CHAR), true, 0);
+-
+- // Get start addr of string and substring
+- Node* str1_valuea = basic_plus_adr(str1, str1, value_offset);
+- Node* str1_value = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
+- Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset);
+- Node* str1_offset = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
++ // Get start addr of string
++ Node* str1_value = load_String_value(no_ctrl, str1);
++ Node* str1_offset = load_String_offset(no_ctrl, str1);
+ Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR);
+
+- Node* str2_valuea = basic_plus_adr(str2, str2, value_offset);
+- Node* str2_value = make_load(no_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
+- Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset);
+- Node* str2_offset = make_load(no_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
++ // Get length of string 1
++ Node* str1_len = load_String_length(no_ctrl, str1);
++
++ Node* str2_value = load_String_value(no_ctrl, str2);
++ Node* str2_offset = load_String_offset(no_ctrl, str2);
+ Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR);
+
++ Node* str2_len = NULL;
+ Node* result = NULL;
++
+ switch (opcode) {
+ case Op_StrIndexOf:
++ // Get length of string 2
++ str2_len = load_String_length(no_ctrl, str2);
++
+ result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
+- str1_start, cnt1, str2_start, cnt2);
++ str1_start, str1_len, str2_start, str2_len);
+ break;
+ case Op_StrComp:
++ // Get length of string 2
++ str2_len = load_String_length(no_ctrl, str2);
++
+ result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
+- str1_start, cnt1, str2_start, cnt2);
++ str1_start, str1_len, str2_start, str2_len);
+ break;
+ case Op_StrEquals:
+ result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
+- str1_start, str2_start, cnt1);
++ str1_start, str2_start, str1_len);
++ break;
++ default:
++ ShouldNotReachHere();
++ return NULL;
++ }
++
++ // All these intrinsics have checks.
++ C->set_has_split_ifs(true); // Has chance for split-if optimization
++
++ return _gvn.transform(result);
++}
++
++// Helper method for String intrinsic functions. This version is called
++// with str1 and str2 pointing to char[] nodes, with cnt1 and cnt2 pointing
++// to Int nodes containing the lenghts of str1 and str2.
++//
++Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2) {
++
++ Node* result = NULL;
++ switch (opcode) {
++ case Op_StrIndexOf:
++ result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
++ str1_start, cnt1, str2_start, cnt2);
++ break;
++ case Op_StrComp:
++ result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
++ str1_start, cnt1, str2_start, cnt2);
++ break;
++ case Op_StrEquals:
++ result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
++ str1_start, str2_start, cnt1);
+ break;
+ default:
+ ShouldNotReachHere();
+@@ -903,10 +932,6 @@
+
+ if (!Matcher::has_match_rule(Op_StrComp)) return false;
+
+- const int value_offset = java_lang_String::value_offset_in_bytes();
+- const int count_offset = java_lang_String::count_offset_in_bytes();
+- const int offset_offset = java_lang_String::offset_offset_in_bytes();
+-
+ _sp += 2;
+ Node *argument = pop(); // pop non-receiver first: it was pushed second
+ Node *receiver = pop();
+@@ -923,18 +948,7 @@
+ return true;
+ }
+
+- ciInstanceKlass* klass = env()->String_klass();
+- const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
+- Node* no_ctrl = NULL;
+-
+- // Get counts for string and argument
+- Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
+- Node* receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
+-
+- Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
+- Node* argument_cnt = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
+-
+- Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt);
++ Node* compare = make_string_method_node(Op_StrComp, receiver, argument);
+ push(compare);
+ return true;
+ }
+@@ -944,10 +958,6 @@
+
+ if (!Matcher::has_match_rule(Op_StrEquals)) return false;
+
+- const int value_offset = java_lang_String::value_offset_in_bytes();
+- const int count_offset = java_lang_String::count_offset_in_bytes();
+- const int offset_offset = java_lang_String::offset_offset_in_bytes();
+-
+ int nargs = 2;
+ _sp += nargs;
+ Node* argument = pop(); // pop non-receiver first: it was pushed second
+@@ -1001,24 +1011,31 @@
+ }
+ }
+
+- const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
+-
+- Node* no_ctrl = NULL;
+- Node* receiver_cnt;
+- Node* argument_cnt;
+-
+ if (!stopped()) {
++ const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
++
+ // Properly cast the argument to String
+ argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type));
+ // This path is taken only when argument's type is String:NotNull.
+ argument = cast_not_null(argument, false);
+
+- // Get counts for string and argument
+- Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
+- receiver_cnt = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
++ Node* no_ctrl = NULL;
++
++ // Get start addr of receiver
++ Node* receiver_val = load_String_value(no_ctrl, receiver);
++ Node* receiver_offset = load_String_offset(no_ctrl, receiver);
++ Node* receiver_start = array_element_address(receiver_val, receiver_offset, T_CHAR);
++
++ // Get length of receiver
++ Node* receiver_cnt = load_String_length(no_ctrl, receiver);
++
++ // Get start addr of argument
++ Node* argument_val = load_String_value(no_ctrl, argument);
++ Node* argument_offset = load_String_offset(no_ctrl, argument);
++ Node* argument_start = array_element_address(argument_val, argument_offset, T_CHAR);
+
+- Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
+- argument_cnt = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
++ // Get length of argument
++ Node* argument_cnt = load_String_length(no_ctrl, argument);
+
+ // Check for receiver count != argument count
+ Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) );
+@@ -1028,14 +1045,14 @@
+ phi->init_req(4, intcon(0));
+ region->init_req(4, if_ne);
+ }
+- }
+
+- // Check for count == 0 is done by mach node StrEquals.
++ // Check for count == 0 is done by assembler code for StrEquals.
+
+- if (!stopped()) {
+- Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt);
+- phi->init_req(1, equals);
+- region->init_req(1, control());
++ if (!stopped()) {
++ Node* equals = make_string_method_node(Op_StrEquals, receiver_start, receiver_cnt, argument_start, argument_cnt);
++ phi->init_req(1, equals);
++ region->init_req(1, control());
++ }
+ }
+
+ // post merge
+@@ -1133,20 +1150,9 @@
+
+ const int nargs = 2; // number of arguments to push back for uncommon trap in predicate
+
+- const int value_offset = java_lang_String::value_offset_in_bytes();
+- const int count_offset = java_lang_String::count_offset_in_bytes();
+- const int offset_offset = java_lang_String::offset_offset_in_bytes();
+-
+- ciInstanceKlass* klass = env()->String_klass();
+- const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
+- const TypeAryPtr* source_type = TypeAryPtr::make(TypePtr::NotNull, TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0);
+-
+- Node* sourceOffseta = basic_plus_adr(string_object, string_object, offset_offset);
+- Node* sourceOffset = make_load(no_ctrl, sourceOffseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
+- Node* sourceCounta = basic_plus_adr(string_object, string_object, count_offset);
+- Node* sourceCount = make_load(no_ctrl, sourceCounta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
+- Node* sourcea = basic_plus_adr(string_object, string_object, value_offset);
+- Node* source = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset));
++ Node* source = load_String_value(no_ctrl, string_object);
++ Node* sourceOffset = load_String_offset(no_ctrl, string_object);
++ Node* sourceCount = load_String_length(no_ctrl, string_object);
+
+ Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) );
+ jint target_length = target_array->length();
+@@ -1214,10 +1220,6 @@
+ //------------------------------inline_string_indexOf------------------------
+ bool LibraryCallKit::inline_string_indexOf() {
+
+- const int value_offset = java_lang_String::value_offset_in_bytes();
+- const int count_offset = java_lang_String::count_offset_in_bytes();
+- const int offset_offset = java_lang_String::offset_offset_in_bytes();
+-
+ _sp += 2;
+ Node *argument = pop(); // pop non-receiver first: it was pushed second
+ Node *receiver = pop();
+@@ -1251,12 +1253,21 @@
+ Node* result_phi = new (C, 4) PhiNode(result_rgn, TypeInt::INT);
+ Node* no_ctrl = NULL;
+
+- // Get counts for string and substr
+- Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset);
+- Node* source_cnt = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
++ // Get start addr of source string
++ Node* source = load_String_value(no_ctrl, receiver);
++ Node* source_offset = load_String_offset(no_ctrl, receiver);
++ Node* source_start = array_element_address(source, source_offset, T_CHAR);
++
++ // Get length of source string
++ Node* source_cnt = load_String_length(no_ctrl, receiver);
++
++ // Get start addr of substring
++ Node* substr = load_String_value(no_ctrl, argument);
++ Node* substr_offset = load_String_offset(no_ctrl, argument);
++ Node* substr_start = array_element_address(substr, substr_offset, T_CHAR);
+
+- Node* substr_cnta = basic_plus_adr(argument, argument, count_offset);
+- Node* substr_cnt = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
++ // Get length of source string
++ Node* substr_cnt = load_String_length(no_ctrl, argument);
+
+ // Check for substr count > string count
+ Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) );
+@@ -1279,7 +1290,7 @@
+ }
+
+ if (!stopped()) {
+- result = make_string_method_node(Op_StrIndexOf, receiver, source_cnt, argument, substr_cnt);
++ result = make_string_method_node(Op_StrIndexOf, source_start, source_cnt, substr_start, substr_cnt);
+ result_phi->init_req(1, result);
+ result_rgn->init_req(1, control());
+ }
+@@ -1304,11 +1315,19 @@
+ ciInstance* str = str_const->as_instance();
+ assert(str != NULL, "must be instance");
+
+- ciObject* v = str->field_value_by_offset(value_offset).as_object();
+- int o = str->field_value_by_offset(offset_offset).as_int();
+- int c = str->field_value_by_offset(count_offset).as_int();
++ ciObject* v = str->field_value_by_offset(java_lang_String::value_offset_in_bytes()).as_object();
+ ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
+
++ int o;
++ int c;
++ if (java_lang_String::has_offset_field()) {
++ o = str->field_value_by_offset(java_lang_String::offset_offset_in_bytes()).as_int();
++ c = str->field_value_by_offset(java_lang_String::count_offset_in_bytes()).as_int();
++ } else {
++ o = 0;
++ c = pat->length();
++ }
++
+ // constant strings have no offset and count == length which
+ // simplifies the resulting code somewhat so lets optimize for that.
+ if (o != 0 || c != pat->length()) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/stringopts.cpp openjdk/hotspot/src/share/vm/opto/stringopts.cpp
+--- openjdk.orig/hotspot/src/share/vm/opto/stringopts.cpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/stringopts.cpp 2013-01-16 00:42:59.099088646 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -528,16 +528,6 @@
+ }
+
+ // Collect the types needed to talk about the various slices of memory
+- const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+- false, NULL, 0);
+-
+- const TypePtr* value_field_type = string_type->add_offset(java_lang_String::value_offset_in_bytes());
+- const TypePtr* offset_field_type = string_type->add_offset(java_lang_String::offset_offset_in_bytes());
+- const TypePtr* count_field_type = string_type->add_offset(java_lang_String::count_offset_in_bytes());
+-
+- value_field_idx = C->get_alias_index(value_field_type);
+- count_field_idx = C->get_alias_index(count_field_type);
+- offset_field_idx = C->get_alias_index(offset_field_type);
+ char_adr_idx = C->get_alias_index(TypeAryPtr::CHARS);
+
+ // For each locally allocated StringBuffer see if the usages can be
+@@ -1173,18 +1163,9 @@
+
+ Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
+ Node* string = str;
+- Node* offset = kit.make_load(kit.control(),
+- kit.basic_plus_adr(string, string, java_lang_String::offset_offset_in_bytes()),
+- TypeInt::INT, T_INT, offset_field_idx);
+- Node* count = kit.make_load(kit.control(),
+- kit.basic_plus_adr(string, string, java_lang_String::count_offset_in_bytes()),
+- TypeInt::INT, T_INT, count_field_idx);
+- const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
+- TypeAry::make(TypeInt::CHAR,TypeInt::POS),
+- ciTypeArrayKlass::make(T_CHAR), true, 0);
+- Node* value = kit.make_load(kit.control(),
+- kit.basic_plus_adr(string, string, java_lang_String::value_offset_in_bytes()),
+- value_type, T_OBJECT, value_field_idx);
++ Node* offset = kit.load_String_offset(kit.control(), string);
++ Node* count = kit.load_String_length(kit.control(), string);
++ Node* value = kit.load_String_value (kit.control(), string);
+
+ // copy the contents
+ if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
+@@ -1341,10 +1322,9 @@
+ arg = phi;
+ sc->set_argument(argi, arg);
+ }
+- // Node* offset = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, offset_offset),
+- // TypeInt::INT, T_INT, offset_field_idx);
+- Node* count = kit.make_load(kit.control(), kit.basic_plus_adr(arg, arg, java_lang_String::count_offset_in_bytes()),
+- TypeInt::INT, T_INT, count_field_idx);
++
++ Node* count = kit.load_String_length(kit.control(), arg);
++
+ length = __ AddI(length, count);
+ string_sizes->init_req(argi, NULL);
+ break;
+@@ -1435,12 +1415,11 @@
+ }
+
+ // Intialize the string
+- kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::offset_offset_in_bytes()),
+- __ intcon(0), T_INT, offset_field_idx);
+- kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::count_offset_in_bytes()),
+- length, T_INT, count_field_idx);
+- kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::value_offset_in_bytes()),
+- char_array, T_OBJECT, value_field_idx);
++ if (java_lang_String::has_offset_field()) {
++ kit.store_String_offset(kit.control(), result, __ intcon(0));
++ kit.store_String_length(kit.control(), result, length);
++ }
++ kit.store_String_value(kit.control(), result, char_array);
+
+ // hook up the outgoing control and result
+ kit.replace_call(sc->end(), result);
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/stringopts.hpp openjdk/hotspot/src/share/vm/opto/stringopts.hpp
+--- openjdk.orig/hotspot/src/share/vm/opto/stringopts.hpp 2012-10-17 08:52:30.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/stringopts.hpp 2013-01-16 00:42:59.103088711 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -41,9 +41,6 @@
+
+ // Memory slices needed for code gen
+ int char_adr_idx;
+- int value_field_idx;
+- int count_field_idx;
+- int offset_field_idx;
+
+ // Integer.sizeTable - used for int to String conversion
+ ciField* size_table_field;
diff --git a/patches/hotspot/zero/7089790-bsd_port.patch b/patches/hotspot/zero/7089790-bsd_port.patch
new file mode 100644
index 0000000..a488004
--- /dev/null
+++ b/patches/hotspot/zero/7089790-bsd_port.patch
@@ -0,0 +1,28881 @@
+diff -Nru openjdk.orig/hotspot/agent/make/Makefile openjdk/hotspot/agent/make/Makefile
+--- openjdk.orig/hotspot/agent/make/Makefile 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/agent/make/Makefile 2013-04-08 01:49:33.578321427 +0100
+@@ -53,6 +53,9 @@
+ sun.jvm.hotspot.compiler \
+ sun.jvm.hotspot.debugger \
+ sun.jvm.hotspot.debugger.amd64 \
++sun.jvm.hotspot.debugger.bsd \
++sun.jvm.hotspot.debugger.bsd.amd64 \
++sun.jvm.hotspot.debugger.bsd.x86 \
+ sun.jvm.hotspot.debugger.cdbg \
+ sun.jvm.hotspot.debugger.cdbg.basic \
+ sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
+@@ -94,6 +97,9 @@
+ sun.jvm.hotspot.prims \
+ sun.jvm.hotspot.runtime \
+ sun.jvm.hotspot.runtime.amd64 \
++sun.jvm.hotspot.runtime.bsd \
++sun.jvm.hotspot.runtime.bsd_amd64 \
++sun.jvm.hotspot.runtime.bsd_x86 \
+ sun.jvm.hotspot.runtime.ia64 \
+ sun.jvm.hotspot.runtime.linux \
+ sun.jvm.hotspot.runtime.linux_amd64 \
+@@ -144,6 +150,9 @@
+ sun/jvm/hotspot/compiler/*.java \
+ sun/jvm/hotspot/debugger/*.java \
+ sun/jvm/hotspot/debugger/amd64/*.java \
++sun/jvm/hotspot/debugger/bsd/*.java \
++sun/jvm/hotspot/debugger/bsd/amd64/*.java \
++sun/jvm/hotspot/debugger/bsd/x86/*.java \
+ sun/jvm/hotspot/debugger/cdbg/*.java \
+ sun/jvm/hotspot/debugger/cdbg/basic/*.java \
+ sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
+@@ -180,6 +189,9 @@
+ sun/jvm/hotspot/prims/*.java \
+ sun/jvm/hotspot/runtime/*.java \
+ sun/jvm/hotspot/runtime/amd64/*.java \
++sun/jvm/hotspot/runtime/bsd/*.java \
++sun/jvm/hotspot/runtime/bsd_amd64/*.java \
++sun/jvm/hotspot/runtime/bsd_x86/*.java \
+ sun/jvm/hotspot/runtime/ia64/*.java \
+ sun/jvm/hotspot/runtime/linux/*.java \
+ sun/jvm/hotspot/runtime/linux_amd64/*.java \
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c openjdk/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,413 @@
++/*
++ * Copyright (c) 2002, 2007, 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 <stdlib.h>
++#include <jni.h>
++#include "libproc.h"
++
++#if defined(x86_64) && !defined(amd64)
++#define amd64 1
++#endif
++
++#ifdef i386
++#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
++#endif
++
++#ifdef amd64
++#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
++#endif
++
++#if defined(sparc) || defined(sparcv9)
++#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
++#endif
++
++static jfieldID p_ps_prochandle_ID = 0;
++static jfieldID threadList_ID = 0;
++static jfieldID loadObjectList_ID = 0;
++
++static jmethodID createClosestSymbol_ID = 0;
++static jmethodID createLoadObject_ID = 0;
++static jmethodID getThreadForThreadId_ID = 0;
++static jmethodID listAdd_ID = 0;
++
++#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);
++}
++
++static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
++ jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
++ return (struct ps_prochandle*)(intptr_t)ptr;
++}
++
++/*
++ * 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) {
++ jclass listClass;
++
++ if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
++ THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
++ }
++
++ // fields we use
++ p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
++ CHECK_EXCEPTION;
++ threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");
++ CHECK_EXCEPTION;
++ loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
++ CHECK_EXCEPTION;
++
++ // methods we use
++ createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
++ "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
++ CHECK_EXCEPTION;
++ createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
++ "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
++ CHECK_EXCEPTION;
++ getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",
++ "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
++ CHECK_EXCEPTION;
++ // java.util.List method we call
++ listClass = (*env)->FindClass(env, "java/util/List");
++ CHECK_EXCEPTION;
++ listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
++ CHECK_EXCEPTION;
++}
++
++JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
++ (JNIEnv *env, jclass cls)
++{
++#ifdef _LP64
++ return 8;
++#else
++ return 4;
++#endif
++
++}
++
++
++static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
++ int n = 0, i = 0;
++
++ // add threads
++ n = get_num_threads(ph);
++ for (i = 0; i < n; i++) {
++ jobject thread;
++ jobject threadList;
++ lwpid_t lwpid;
++
++ lwpid = get_lwp_id(ph, i);
++ thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,
++ (jlong)lwpid);
++ CHECK_EXCEPTION;
++ threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);
++ CHECK_EXCEPTION;
++ (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);
++ CHECK_EXCEPTION;
++ }
++
++ // add load objects
++ n = get_num_libs(ph);
++ for (i = 0; i < n; i++) {
++ uintptr_t base;
++ const char* name;
++ jobject loadObject;
++ jobject loadObjectList;
++
++ base = get_lib_base(ph, i);
++ name = get_lib_name(ph, i);
++ loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
++ (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
++ CHECK_EXCEPTION;
++ loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
++ CHECK_EXCEPTION;
++ (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
++ CHECK_EXCEPTION;
++ }
++}
++
++/*
++ * 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) {
++
++ struct ps_prochandle* ph;
++ if ( (ph = Pgrab(jpid)) == NULL) {
++ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
++ }
++ (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
++ fillThreadsAndLoadObjects(env, this_obj, ph);
++}
++
++/*
++ * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
++ * Method: attach0
++ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
++ */
++JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
++ (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
++ const char *execName_cstr;
++ const char *coreName_cstr;
++ jboolean isCopy;
++ struct ps_prochandle* ph;
++
++ execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
++ CHECK_EXCEPTION;
++ coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
++ CHECK_EXCEPTION;
++
++ if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
++ (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
++ (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
++ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
++ }
++ (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
++ (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
++ (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
++ fillThreadsAndLoadObjects(env, this_obj, ph);
++}
++
++/*
++ * 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) {
++ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
++ if (ph != NULL) {
++ Prelease(ph);
++ }
++}
++
++/*
++ * 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) {
++ const char *objectName_cstr, *symbolName_cstr;
++ jlong addr;
++ jboolean isCopy;
++ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
++
++ objectName_cstr = NULL;
++ if (objectName != NULL) {
++ objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
++ CHECK_EXCEPTION_(0);
++ }
++ symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);
++ CHECK_EXCEPTION_(0);
++
++ addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
++
++ if (objectName_cstr != NULL) {
++ (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);
++ }
++ (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);
++ return addr;
++}
++
++/*
++ * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
++ * Method: lookupByAddress0
++ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
++ */
++JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
++ (JNIEnv *env, jobject this_obj, jlong addr) {
++ uintptr_t offset;
++ const char* sym = NULL;
++
++ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
++ sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
++ if (sym == NULL) return 0;
++ return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,
++ (*env)->NewStringUTF(env, sym), (jlong)offset);
++}
++
++/*
++ * 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) {
++
++ jboolean isCopy;
++ jbyteArray array;
++ jbyte *bufPtr;
++ ps_err_e err;
++
++ array = (*env)->NewByteArray(env, numBytes);
++ CHECK_EXCEPTION_(0);
++ bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
++ CHECK_EXCEPTION_(0);
++
++ err = ps_pread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);
++ (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);
++ return (err == PS_OK)? array : 0;
++}
++
++JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
++ (JNIEnv *env, jobject this_obj, jint lwp_id) {
++
++ struct reg gregs;
++ jboolean isCopy;
++ jlongArray array;
++ jlong *regs;
++
++ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
++ if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
++ THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
++ }
++
++#undef NPRGREG
++#ifdef i386
++#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
++#endif
++#ifdef ia64
++#define NPRGREG IA64_REG_COUNT
++#endif
++#ifdef amd64
++#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
++#endif
++#if defined(sparc) || defined(sparcv9)
++#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
++#endif
++
++ array = (*env)->NewLongArray(env, NPRGREG);
++ CHECK_EXCEPTION_(0);
++ regs = (*env)->GetLongArrayElements(env, array, &isCopy);
++
++#undef REG_INDEX
++
++#ifdef i386
++#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
++
++ regs[REG_INDEX(GS)] = (uintptr_t) gregs.r_gs;
++ regs[REG_INDEX(FS)] = (uintptr_t) gregs.r_fs;
++ regs[REG_INDEX(ES)] = (uintptr_t) gregs.r_es;
++ regs[REG_INDEX(DS)] = (uintptr_t) gregs.r_ds;
++ regs[REG_INDEX(EDI)] = (uintptr_t) gregs.r_edi;
++ regs[REG_INDEX(ESI)] = (uintptr_t) gregs.r_esi;
++ regs[REG_INDEX(FP)] = (uintptr_t) gregs.r_ebp;
++ regs[REG_INDEX(SP)] = (uintptr_t) gregs.r_isp;
++ regs[REG_INDEX(EBX)] = (uintptr_t) gregs.r_ebx;
++ regs[REG_INDEX(EDX)] = (uintptr_t) gregs.r_edx;
++ regs[REG_INDEX(ECX)] = (uintptr_t) gregs.r_ecx;
++ regs[REG_INDEX(EAX)] = (uintptr_t) gregs.r_eax;
++ regs[REG_INDEX(PC)] = (uintptr_t) gregs.r_eip;
++ regs[REG_INDEX(CS)] = (uintptr_t) gregs.r_cs;
++ regs[REG_INDEX(SS)] = (uintptr_t) gregs.r_ss;
++
++#endif /* i386 */
++
++#if ia64
++ regs = (*env)->GetLongArrayElements(env, array, &isCopy);
++ int i;
++ for (i = 0; i < NPRGREG; i++ ) {
++ regs[i] = 0xDEADDEAD;
++ }
++#endif /* ia64 */
++
++#ifdef amd64
++#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
++
++ regs[REG_INDEX(R15)] = gregs.r_r15;
++ regs[REG_INDEX(R14)] = gregs.r_r14;
++ regs[REG_INDEX(R13)] = gregs.r_r13;
++ regs[REG_INDEX(R12)] = gregs.r_r12;
++ regs[REG_INDEX(RBP)] = gregs.r_rbp;
++ regs[REG_INDEX(RBX)] = gregs.r_rbx;
++ regs[REG_INDEX(R11)] = gregs.r_r11;
++ regs[REG_INDEX(R10)] = gregs.r_r10;
++ regs[REG_INDEX(R9)] = gregs.r_r9;
++ regs[REG_INDEX(R8)] = gregs.r_r8;
++ regs[REG_INDEX(RAX)] = gregs.r_rax;
++ regs[REG_INDEX(RCX)] = gregs.r_rcx;
++ regs[REG_INDEX(RDX)] = gregs.r_rdx;
++ regs[REG_INDEX(RSI)] = gregs.r_rsi;
++ regs[REG_INDEX(RDI)] = gregs.r_rdi;
++ regs[REG_INDEX(RIP)] = gregs.r_rip;
++ regs[REG_INDEX(CS)] = gregs.r_cs;
++ regs[REG_INDEX(RSP)] = gregs.r_rsp;
++ regs[REG_INDEX(SS)] = gregs.r_ss;
++// regs[REG_INDEX(FSBASE)] = gregs.fs_base;
++// regs[REG_INDEX(GSBASE)] = gregs.gs_base;
++// regs[REG_INDEX(DS)] = gregs.ds;
++// regs[REG_INDEX(ES)] = gregs.es;
++// regs[REG_INDEX(FS)] = gregs.fs;
++// regs[REG_INDEX(GS)] = gregs.gs;
++
++#endif /* amd64 */
++
++#if defined(sparc) || defined(sparcv9)
++
++#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg
++
++#ifdef _LP64
++ regs[REG_INDEX(R_PSR)] = gregs.tstate;
++ regs[REG_INDEX(R_PC)] = gregs.tpc;
++ regs[REG_INDEX(R_nPC)] = gregs.tnpc;
++ regs[REG_INDEX(R_Y)] = gregs.y;
++#else
++ regs[REG_INDEX(R_PSR)] = gregs.psr;
++ regs[REG_INDEX(R_PC)] = gregs.pc;
++ regs[REG_INDEX(R_nPC)] = gregs.npc;
++ regs[REG_INDEX(R_Y)] = gregs.y;
++#endif
++ regs[REG_INDEX(R_G0)] = 0 ;
++ regs[REG_INDEX(R_G1)] = gregs.u_regs[0];
++ regs[REG_INDEX(R_G2)] = gregs.u_regs[1];
++ regs[REG_INDEX(R_G3)] = gregs.u_regs[2];
++ regs[REG_INDEX(R_G4)] = gregs.u_regs[3];
++ regs[REG_INDEX(R_G5)] = gregs.u_regs[4];
++ regs[REG_INDEX(R_G6)] = gregs.u_regs[5];
++ regs[REG_INDEX(R_G7)] = gregs.u_regs[6];
++ regs[REG_INDEX(R_O0)] = gregs.u_regs[7];
++ regs[REG_INDEX(R_O1)] = gregs.u_regs[8];
++ regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9];
++ regs[REG_INDEX(R_O3)] = gregs.u_regs[10];
++ regs[REG_INDEX(R_O4)] = gregs.u_regs[11];
++ regs[REG_INDEX(R_O5)] = gregs.u_regs[12];
++ regs[REG_INDEX(R_O6)] = gregs.u_regs[13];
++ regs[REG_INDEX(R_O7)] = gregs.u_regs[14];
++#endif /* sparc */
++
++
++ (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
++ return array;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/elfmacros.h openjdk/hotspot/agent/src/os/bsd/elfmacros.h
+--- openjdk.orig/hotspot/agent/src/os/bsd/elfmacros.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/elfmacros.h 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2003, 2006, 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 _ELFMACROS_H_
++#define _ELFMACROS_H_
++
++#define ELF_NHDR Elf_Note
++
++#if defined(_LP64)
++#define ELF_EHDR Elf64_Ehdr
++#define ELF_SHDR Elf64_Shdr
++#define ELF_PHDR Elf64_Phdr
++#define ELF_SYM Elf64_Sym
++#define ELF_DYN Elf64_Dyn
++#define ELF_ADDR Elf64_Addr
++
++#ifndef ELF_ST_TYPE
++#define ELF_ST_TYPE ELF64_ST_TYPE
++#endif
++
++#else
++
++#define ELF_EHDR Elf32_Ehdr
++#define ELF_SHDR Elf32_Shdr
++#define ELF_PHDR Elf32_Phdr
++#define ELF_SYM Elf32_Sym
++#define ELF_DYN Elf32_Dyn
++#define ELF_ADDR Elf32_Addr
++
++#ifndef ELF_ST_TYPE
++#define ELF_ST_TYPE ELF32_ST_TYPE
++#endif
++
++#endif
++
++
++#endif /* _ELFMACROS_H_ */
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/libproc.h openjdk/hotspot/agent/src/os/bsd/libproc.h
+--- openjdk.orig/hotspot/agent/src/os/bsd/libproc.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/libproc.h 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,127 @@
++/*
++ * Copyright (c) 2003, 2007, 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 _LIBPROC_H_
++#define _LIBPROC_H_
++
++#include <unistd.h>
++#include <stdint.h>
++#include <machine/reg.h>
++#include <proc_service.h>
++
++#if defined(sparc) || defined(sparcv9)
++/*
++ If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
++ otherwise it should be from /usr/include/asm-sparc
++ These two files define pt_regs structure differently
++*/
++#ifdef _LP64
++#include "asm-sparc64/ptrace.h"
++#else
++#include "asm-sparc/ptrace.h"
++#endif
++
++#endif //sparc or sparcv9
++
++/************************************************************************************
++
++0. This is very minimal subset of Solaris libproc just enough for current application.
++Please note that the bulk of the functionality is from proc_service interface. This
++adds Pgrab__ and some missing stuff. We hide the difference b/w live process and core
++file by this interface.
++
++1. pthread_id is unique. We store this in OSThread::_pthread_id in JVM code.
++
++2. All threads see the same pid when they call getpid().
++We used to save the result of ::getpid() call in OSThread::_thread_id.
++Because gettid returns actual pid of thread (lwp id), this is
++unique again. We therefore use OSThread::_thread_id as unique identifier.
++
++3. There is a unique LWP id under both thread libraries. libthread_db maps pthread_id
++to its underlying lwp_id under both the thread libraries. thread_info.lwp_id stores
++lwp_id of the thread. The lwp id is nothing but the actual pid of clone'd processes. But
++unfortunately libthread_db does not work very well for core dumps. So, we get pthread_id
++only for processes. For core dumps, we don't use libthread_db at all (like gdb).
++
++4. ptrace operates on this LWP id under both the thread libraries. When we say 'pid' for
++ptrace call, we refer to lwp_id of the thread.
++
++5. for core file, we parse ELF files and read data from them. For processes we use
++combination of ptrace and /proc calls.
++
++*************************************************************************************/
++
++// This C bool type must be int for compatibility with BSD calls and
++// it would be a mistake to equivalence it to C++ bool on many platforms
++
++typedef int bool;
++#define true 1
++#define false 0
++
++struct ps_prochandle;
++
++// attach to a process
++struct ps_prochandle* Pgrab(pid_t pid);
++
++// attach to a core dump
++struct ps_prochandle* Pgrab_core(const char* execfile, const char* corefile);
++
++// release a process or core
++void Prelease(struct ps_prochandle* ph);
++
++// functions not directly available in Solaris libproc
++
++// initialize libproc (call this only once per app)
++// pass true to make library verbose
++bool init_libproc(bool verbose);
++
++// get number of threads
++int get_num_threads(struct ps_prochandle* ph);
++
++// get lwp_id of n'th thread
++lwpid_t get_lwp_id(struct ps_prochandle* ph, int index);
++
++// get regs for a given lwp
++bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lid, struct reg* regs);
++
++// get number of shared objects
++int get_num_libs(struct ps_prochandle* ph);
++
++// get name of n'th lib
++const char* get_lib_name(struct ps_prochandle* ph, int index);
++
++// get base of lib
++uintptr_t get_lib_base(struct ps_prochandle* ph, int index);
++
++// returns true if given library is found in lib list
++bool find_lib(struct ps_prochandle* ph, const char *lib_name);
++
++// symbol lookup
++uintptr_t lookup_symbol(struct ps_prochandle* ph, const char* object_name,
++ const char* sym_name);
++
++// address->nearest symbol lookup. return NULL for no symbol
++const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset);
++
++#endif //__LIBPROC_H_
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/libproc_impl.c openjdk/hotspot/agent/src/os/bsd/libproc_impl.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/libproc_impl.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/libproc_impl.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,452 @@
++/*
++ * 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 <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <fcntl.h>
++#include <thread_db.h>
++#include "libproc_impl.h"
++
++static const char* alt_root = NULL;
++static int alt_root_len = -1;
++
++#define SA_ALTROOT "SA_ALTROOT"
++
++static void init_alt_root() {
++ if (alt_root_len == -1) {
++ alt_root = getenv(SA_ALTROOT);
++ if (alt_root) {
++ alt_root_len = strlen(alt_root);
++ } else {
++ alt_root_len = 0;
++ }
++ }
++}
++
++int pathmap_open(const char* name) {
++ int fd;
++ char alt_path[PATH_MAX + 1];
++
++ init_alt_root();
++ fd = open(name, O_RDONLY);
++ if (fd >= 0) {
++ return fd;
++ }
++
++ if (alt_root_len > 0) {
++ strcpy(alt_path, alt_root);
++ strcat(alt_path, name);
++ fd = open(alt_path, O_RDONLY);
++ if (fd >= 0) {
++ print_debug("path %s substituted for %s\n", alt_path, name);
++ return fd;
++ }
++
++ if (strrchr(name, '/')) {
++ strcpy(alt_path, alt_root);
++ strcat(alt_path, strrchr(name, '/'));
++ fd = open(alt_path, O_RDONLY);
++ if (fd >= 0) {
++ print_debug("path %s substituted for %s\n", alt_path, name);
++ return fd;
++ }
++ }
++ }
++
++ return -1;
++}
++
++static bool _libsaproc_debug;
++
++void print_debug(const char* format,...) {
++ if (_libsaproc_debug) {
++ va_list alist;
++
++ va_start(alist, format);
++ fputs("libsaproc DEBUG: ", stderr);
++ vfprintf(stderr, format, alist);
++ va_end(alist);
++ }
++}
++
++bool is_debug() {
++ return _libsaproc_debug;
++}
++
++// initialize libproc
++bool init_libproc(bool debug) {
++ // init debug mode
++ _libsaproc_debug = debug;
++
++ // initialize the thread_db library
++ if (td_init() != TD_OK) {
++ print_debug("libthread_db's td_init failed\n");
++ return false;
++ }
++
++ return true;
++}
++
++static void destroy_lib_info(struct ps_prochandle* ph) {
++ lib_info* lib = ph->libs;
++ while (lib) {
++ lib_info *next = lib->next;
++ if (lib->symtab) {
++ destroy_symtab(lib->symtab);
++ }
++ free(lib);
++ lib = next;
++ }
++}
++
++static void destroy_thread_info(struct ps_prochandle* ph) {
++ thread_info* thr = ph->threads;
++ while (thr) {
++ thread_info *next = thr->next;
++ free(thr);
++ thr = next;
++ }
++}
++
++// ps_prochandle cleanup
++
++// ps_prochandle cleanup
++void Prelease(struct ps_prochandle* ph) {
++ // do the "derived class" clean-up first
++ ph->ops->release(ph);
++ destroy_lib_info(ph);
++ destroy_thread_info(ph);
++ free(ph);
++}
++
++lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
++ return add_lib_info_fd(ph, libname, -1, base);
++}
++
++lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
++ lib_info* newlib;
++
++ if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
++ print_debug("can't allocate memory for lib_info\n");
++ return NULL;
++ }
++
++ strncpy(newlib->name, libname, sizeof(newlib->name));
++ newlib->base = base;
++
++ if (fd == -1) {
++ if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
++ print_debug("can't open shared object %s\n", newlib->name);
++ free(newlib);
++ return NULL;
++ }
++ } else {
++ newlib->fd = fd;
++ }
++
++ // check whether we have got an ELF file. /proc/<pid>/map
++ // gives out all file mappings and not just shared objects
++ if (is_elf_file(newlib->fd) == false) {
++ close(newlib->fd);
++ free(newlib);
++ return NULL;
++ }
++
++ newlib->symtab = build_symtab(newlib->fd);
++ if (newlib->symtab == NULL) {
++ print_debug("symbol table build failed for %s\n", newlib->name);
++ }
++ else {
++ print_debug("built symbol table for %s\n", newlib->name);
++ }
++
++ // even if symbol table building fails, we add the lib_info.
++ // This is because we may need to read from the ELF file for core file
++ // address read functionality. lookup_symbol checks for NULL symtab.
++ if (ph->libs) {
++ ph->lib_tail->next = newlib;
++ ph->lib_tail = newlib;
++ } else {
++ ph->libs = ph->lib_tail = newlib;
++ }
++ ph->num_libs++;
++
++ return newlib;
++}
++
++// lookup for a specific symbol
++uintptr_t lookup_symbol(struct ps_prochandle* ph, const char* object_name,
++ const char* sym_name) {
++ // ignore object_name. search in all libraries
++ // FIXME: what should we do with object_name?? The library names are obtained
++ // by parsing /proc/<pid>/maps, which may not be the same as object_name.
++ // What we need is a utility to map object_name to real file name, something
++ // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
++ // now, we just ignore object_name and do a global search for the symbol.
++
++ lib_info* lib = ph->libs;
++ while (lib) {
++ if (lib->symtab) {
++ uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL);
++ if (res) return res;
++ }
++ lib = lib->next;
++ }
++
++ print_debug("lookup failed for symbol '%s' in obj '%s'\n",
++ sym_name, object_name);
++ return (uintptr_t) NULL;
++}
++
++
++const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) {
++ const char* res = NULL;
++ lib_info* lib = ph->libs;
++ while (lib) {
++ if (lib->symtab && addr >= lib->base) {
++ res = nearest_symbol(lib->symtab, addr - lib->base, poffset);
++ if (res) return res;
++ }
++ lib = lib->next;
++ }
++ return NULL;
++}
++
++// add a thread to ps_prochandle
++thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
++ thread_info* newthr;
++ if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
++ print_debug("can't allocate memory for thread_info\n");
++ return NULL;
++ }
++
++ // initialize thread info
++ newthr->pthread_id = pthread_id;
++ newthr->lwp_id = lwp_id;
++
++ // add new thread to the list
++ newthr->next = ph->threads;
++ ph->threads = newthr;
++ ph->num_threads++;
++ return newthr;
++}
++
++
++// struct used for client data from thread_db callback
++struct thread_db_client_data {
++ struct ps_prochandle* ph;
++ thread_info_callback callback;
++};
++
++// callback function for libthread_db
++static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
++ struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
++ td_thrinfo_t ti;
++ td_err_e err;
++
++ memset(&ti, 0, sizeof(ti));
++ err = td_thr_get_info(th_p, &ti);
++ if (err != TD_OK) {
++ print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
++ return err;
++ }
++
++ print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
++
++ if (ptr->callback(ptr->ph, (pthread_t)ti.ti_tid, ti.ti_lid) != true)
++ return TD_ERR;
++
++ return TD_OK;
++}
++
++// read thread_info using libthread_db
++bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
++ struct thread_db_client_data mydata;
++ td_thragent_t* thread_agent = NULL;
++ if (td_ta_new(ph, &thread_agent) != TD_OK) {
++ print_debug("can't create libthread_db agent\n");
++ return false;
++ }
++
++ mydata.ph = ph;
++ mydata.callback = cb;
++
++ // we use libthread_db iterator to iterate thru list of threads.
++ if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
++ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
++ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
++ td_ta_delete(thread_agent);
++ return false;
++ }
++
++ // delete thread agent
++ td_ta_delete(thread_agent);
++ return true;
++}
++
++
++// get number of threads
++int get_num_threads(struct ps_prochandle* ph) {
++ return ph->num_threads;
++}
++
++// get lwp_id of n'th thread
++lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
++ int count = 0;
++ thread_info* thr = ph->threads;
++ while (thr) {
++ if (count == index) {
++ return thr->lwp_id;
++ }
++ count++;
++ thr = thr->next;
++ }
++ return -1;
++}
++
++// get regs for a given lwp
++bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) {
++ return ph->ops->get_lwp_regs(ph, lwp_id, regs);
++}
++
++// get number of shared objects
++int get_num_libs(struct ps_prochandle* ph) {
++ return ph->num_libs;
++}
++
++// get name of n'th solib
++const char* get_lib_name(struct ps_prochandle* ph, int index) {
++ int count = 0;
++ lib_info* lib = ph->libs;
++ while (lib) {
++ if (count == index) {
++ return lib->name;
++ }
++ count++;
++ lib = lib->next;
++ }
++ return NULL;
++}
++
++// get base address of a lib
++uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
++ int count = 0;
++ lib_info* lib = ph->libs;
++ while (lib) {
++ if (count == index) {
++ return lib->base;
++ }
++ count++;
++ lib = lib->next;
++ }
++ return (uintptr_t)NULL;
++}
++
++bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
++ lib_info *p = ph->libs;
++ while (p) {
++ if (strcmp(p->name, lib_name) == 0) {
++ return true;
++ }
++ p = p->next;
++ }
++ return false;
++}
++
++//--------------------------------------------------------------------------
++// proc service functions
++
++// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
++// of the load object object_name in the target process identified by ph.
++// It returns the symbol's value as an address in the target process in
++// *sym_addr.
++
++ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
++ const char *sym_name, psaddr_t *sym_addr) {
++ *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name);
++ return (*sym_addr ? PS_OK : PS_NOSYM);
++}
++
++// read "size" bytes info "buf" from address "addr"
++ps_err_e ps_pread(struct ps_prochandle *ph, psaddr_t addr,
++ void *buf, size_t size) {
++ return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR;
++}
++
++// write "size" bytes of data to debuggee at address "addr"
++ps_err_e ps_pwrite(struct ps_prochandle *ph, psaddr_t addr,
++ const void *buf, size_t size) {
++ return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR;
++}
++
++// fill in ptrace_lwpinfo for lid
++ps_err_e ps_linfo(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
++ return ph->ops->get_lwp_info(ph, lwp_id, linfo)? PS_OK: PS_ERR;
++}
++
++// needed for when libthread_db is compiled with TD_DEBUG defined
++void
++ps_plog (const char *format, ...)
++{
++ va_list alist;
++
++ va_start(alist, format);
++ vfprintf(stderr, format, alist);
++ va_end(alist);
++}
++
++// ------------------------------------------------------------------------
++// Functions below this point are not yet implemented. They are here only
++// to make the linker happy.
++
++ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) {
++ print_debug("ps_lsetfpregs not implemented\n");
++ return PS_OK;
++}
++
++ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) {
++ print_debug("ps_lsetregs not implemented\n");
++ return PS_OK;
++}
++
++ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *fpregs) {
++ print_debug("ps_lgetfpregs not implemented\n");
++ return PS_OK;
++}
++
++ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) {
++ print_debug("ps_lgetfpregs not implemented\n");
++ return PS_OK;
++}
++
++ps_err_e ps_lstop(struct ps_prochandle *ph, lwpid_t lid) {
++ print_debug("ps_lstop not implemented\n");
++ return PS_OK;
++}
++
++ps_err_e ps_pcontinue(struct ps_prochandle *ph) {
++ print_debug("ps_pcontinue not implemented\n");
++ return PS_OK;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/libproc_impl.h openjdk/hotspot/agent/src/os/bsd/libproc_impl.h
+--- openjdk.orig/hotspot/agent/src/os/bsd/libproc_impl.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/libproc_impl.h 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (c) 2003, 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.
++ *
++ */
++
++#ifndef _LIBPROC_IMPL_H_
++#define _LIBPROC_IMPL_H_
++
++#include <unistd.h>
++#include <limits.h>
++#include "libproc.h"
++#include "symtab.h"
++
++// data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
++
++#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
++
++// list of shared objects
++typedef struct lib_info {
++ char name[BUF_SIZE];
++ uintptr_t base;
++ struct symtab* symtab;
++ int fd; // file descriptor for lib
++ struct lib_info* next;
++} lib_info;
++
++// list of threads
++typedef struct thread_info {
++ lwpid_t lwp_id;
++ pthread_t pthread_id; // not used cores, always -1
++ struct reg regs; // not for process, core uses for caching regset
++ struct thread_info* next;
++} thread_info;
++
++// list of virtual memory maps
++typedef struct map_info {
++ int fd; // file descriptor
++ off_t offset; // file offset of this mapping
++ uintptr_t vaddr; // starting virtual address
++ size_t memsz; // size of the mapping
++ struct map_info* next;
++} map_info;
++
++// vtable for ps_prochandle
++typedef struct ps_prochandle_ops {
++ // "derived class" clean-up
++ void (*release)(struct ps_prochandle* ph);
++ // read from debuggee
++ bool (*p_pread)(struct ps_prochandle *ph,
++ uintptr_t addr, char *buf, size_t size);
++ // write into debuggee
++ bool (*p_pwrite)(struct ps_prochandle *ph,
++ uintptr_t addr, const char *buf , size_t size);
++ // get integer regset of a thread
++ bool (*get_lwp_regs)(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs);
++ // get info on thread
++ bool (*get_lwp_info)(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo);
++} ps_prochandle_ops;
++
++// the ps_prochandle
++
++struct core_data {
++ int core_fd; // file descriptor of core file
++ int exec_fd; // file descriptor of exec file
++ int interp_fd; // file descriptor of interpreter (ld-elf.so.1)
++ // part of the class sharing workaround
++ int classes_jsa_fd; // file descriptor of class share archive
++ uintptr_t dynamic_addr; // address of dynamic section of a.out
++ uintptr_t ld_base_addr; // base address of ld.so
++ size_t num_maps; // number of maps.
++ map_info* maps; // maps in a linked list
++ // part of the class sharing workaround
++ map_info* class_share_maps;// class share maps in a linked list
++ map_info** map_array; // sorted (by vaddr) array of map_info pointers
++};
++
++struct ps_prochandle {
++ ps_prochandle_ops* ops; // vtable ptr
++ pid_t pid;
++ int num_libs;
++ lib_info* libs; // head of lib list
++ lib_info* lib_tail; // tail of lib list - to append at the end
++ int num_threads;
++ thread_info* threads; // head of thread list
++ struct core_data* core; // data only used for core dumps, NULL for process
++};
++
++int pathmap_open(const char* name);
++
++void print_debug(const char* format,...);
++bool is_debug();
++
++typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
++
++// reads thread info using libthread_db and calls above callback for each thread
++bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb);
++
++// adds a new shared object to lib list, returns NULL on failure
++lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base);
++
++// adds a new shared object to lib list, supply open lib file descriptor as well
++lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
++ uintptr_t base);
++
++// adds a new thread to threads list, returns NULL on failure
++thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
++
++// a test for ELF signature without using libelf
++bool is_elf_file(int fd);
++
++#endif //_LIBPROC_IMPL_H_
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/Makefile openjdk/hotspot/agent/src/os/bsd/Makefile
+--- openjdk.orig/hotspot/agent/src/os/bsd/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/Makefile 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,78 @@
++#
++# Copyright (c) 2002, 2009, 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.
++#
++#
++
++ARCH := $(shell if ([ `uname -m` = "ia64" ]) ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi )
++GCC = gcc
++
++JAVAH = ${JAVA_HOME}/bin/javah
++
++SOURCES = salibelf.c \
++ symtab.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:]")
++
++OBJS = $(SOURCES:.c=.o)
++
++LIBS = -lutil -lthread_db
++
++CFLAGS = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
++
++LIBSA = $(ARCH)/libsaproc.so
++
++all: $(LIBSA)
++
++BsdDebuggerLocal.o: BsdDebuggerLocal.c
++ $(JAVAH) -jni -classpath ../../../../../build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/generated/saclasses \
++ sun.jvm.hotspot.debugger.x86.X86ThreadContext \
++ sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
++ $(GCC) $(CFLAGS) $<
++
++.c.obj:
++ $(GCC) $(CFLAGS)
++
++ifndef LDNOMAP
++ LFLAGS_LIBSA = -Xlinker --version-script=mapfile
++endif
++
++$(LIBSA): $(OBJS) mapfile
++ if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi
++ $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
++
++test.o: $(LIBSA) test.c
++ $(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c
++
++test: test.o
++ $(GCC) -o test test.o -L$(ARCH) -lsaproc $(LIBS)
++
++clean:
++ rm -f $(LIBSA)
++ rm -f $(OBJS)
++ rm -f test.o
++ -rmdir $(ARCH)
++
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/mapfile openjdk/hotspot/agent/src/os/bsd/mapfile
+--- openjdk.orig/hotspot/agent/src/os/bsd/mapfile 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/mapfile 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,66 @@
++#
++
++#
++# Copyright (c) 2003, 2006, 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.
++#
++#
++
++# Define public interface.
++
++SUNWprivate_1.1 {
++ global:
++
++ # native methods of BsdDebuggerLocal class
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0;
++ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0;
++
++ # proc_service.h functions - to be used by libthread_db
++ ps_getpid;
++ ps_pglobal_lookup;
++ ps_pread;
++ ps_pwrite;
++ ps_lsetfpregs;
++ ps_lsetregs;
++ ps_lgetfpregs;
++ ps_lgetregs;
++ ps_lcontinue;
++ ps_lgetxmmregs;
++ ps_lsetxmmregs;
++ ps_lstop;
++ ps_linfo;
++
++ # used by attach test program
++ init_libproc;
++ Pgrab;
++ Pgrab_core;
++ Prelease;
++
++ local:
++ *;
++};
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/ps_core.c openjdk/hotspot/agent/src/os/bsd/ps_core.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/ps_core.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/ps_core.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,1023 @@
++/*
++ * 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 <jni.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <string.h>
++#include <stdlib.h>
++#include <stddef.h>
++#include <elf.h>
++#include <link.h>
++#include "libproc_impl.h"
++#include "salibelf.h"
++
++// This file has the libproc implementation to read core files.
++// For live processes, refer to ps_proc.c. Portions of this is adapted
++// /modelled after Solaris libproc.so (in particular Pcore.c)
++
++//----------------------------------------------------------------------
++// ps_prochandle cleanup helper functions
++
++// close all file descriptors
++static void close_elf_files(struct ps_prochandle* ph) {
++ lib_info* lib = NULL;
++
++ // close core file descriptor
++ if (ph->core->core_fd >= 0)
++ close(ph->core->core_fd);
++
++ // close exec file descriptor
++ if (ph->core->exec_fd >= 0)
++ close(ph->core->exec_fd);
++
++ // close interp file descriptor
++ if (ph->core->interp_fd >= 0)
++ close(ph->core->interp_fd);
++
++ // close class share archive file
++ if (ph->core->classes_jsa_fd >= 0)
++ close(ph->core->classes_jsa_fd);
++
++ // close all library file descriptors
++ lib = ph->libs;
++ while (lib) {
++ int fd = lib->fd;
++ if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
++ lib = lib->next;
++ }
++}
++
++// clean all map_info stuff
++static void destroy_map_info(struct ps_prochandle* ph) {
++ map_info* map = ph->core->maps;
++ while (map) {
++ map_info* next = map->next;
++ free(map);
++ map = next;
++ }
++
++ if (ph->core->map_array) {
++ free(ph->core->map_array);
++ }
++
++ // Part of the class sharing workaround
++ map = ph->core->class_share_maps;
++ while (map) {
++ map_info* next = map->next;
++ free(map);
++ map = next;
++ }
++}
++
++// ps_prochandle operations
++static void core_release(struct ps_prochandle* ph) {
++ if (ph->core) {
++ close_elf_files(ph);
++ destroy_map_info(ph);
++ free(ph->core);
++ }
++}
++
++static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
++ map_info* map;
++ if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
++ print_debug("can't allocate memory for map_info\n");
++ return NULL;
++ }
++
++ // initialize map
++ map->fd = fd;
++ map->offset = offset;
++ map->vaddr = vaddr;
++ map->memsz = memsz;
++ return map;
++}
++
++// add map info with given fd, offset, vaddr and memsz
++static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
++ uintptr_t vaddr, size_t memsz) {
++ map_info* map;
++ if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
++ return NULL;
++ }
++
++ // add this to map list
++ map->next = ph->core->maps;
++ ph->core->maps = map;
++ ph->core->num_maps++;
++
++ return map;
++}
++
++// Part of the class sharing workaround
++static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
++ uintptr_t vaddr, size_t memsz) {
++ map_info* map;
++ if ((map = allocate_init_map(ph->core->classes_jsa_fd,
++ offset, vaddr, memsz)) == NULL) {
++ return NULL;
++ }
++
++ map->next = ph->core->class_share_maps;
++ ph->core->class_share_maps = map;
++ return map;
++}
++
++// Return the map_info for the given virtual address. We keep a sorted
++// array of pointers in ph->map_array, so we can binary search.
++static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
++{
++ int mid, lo = 0, hi = ph->core->num_maps - 1;
++ map_info *mp;
++
++ while (hi - lo > 1) {
++ mid = (lo + hi) / 2;
++ if (addr >= ph->core->map_array[mid]->vaddr)
++ lo = mid;
++ else
++ hi = mid;
++ }
++
++ if (addr < ph->core->map_array[hi]->vaddr)
++ mp = ph->core->map_array[lo];
++ else
++ mp = ph->core->map_array[hi];
++
++ if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
++ return (mp);
++
++
++ // Part of the class sharing workaround
++ // Unfortunately, we have no way of detecting -Xshare state.
++ // Check out the share maps atlast, if we don't find anywhere.
++ // This is done this way so to avoid reading share pages
++ // ahead of other normal maps. For eg. with -Xshare:off we don't
++ // want to prefer class sharing data to data from core.
++ mp = ph->core->class_share_maps;
++ if (mp) {
++ print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
++ addr);
++ }
++ while (mp) {
++ if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
++ print_debug("located map_info at 0x%lx from class share maps\n",
++ addr);
++ return (mp);
++ }
++ mp = mp->next;
++ }
++
++ print_debug("can't locate map_info at 0x%lx\n", addr);
++ return (NULL);
++}
++
++//---------------------------------------------------------------
++// Part of the class sharing workaround:
++//
++// With class sharing, pages are mapped from classes[_g].jsa file.
++// The read-only class sharing pages are mapped as MAP_SHARED,
++// PROT_READ pages. These pages are not dumped into core dump.
++// With this workaround, these pages are read from classes[_g].jsa.
++
++// FIXME: !HACK ALERT!
++// The format of sharing achive file header is needed to read shared heap
++// file mappings. For now, I am hard coding portion of FileMapHeader here.
++// Refer to filemap.hpp.
++
++// FileMapHeader describes the shared space data in the file to be
++// mapped. This structure gets written to a file. It is not a class,
++// so that the compilers don't add any compiler-private data to it.
++
++// Refer to CompactingPermGenGen::n_regions in compactingPermGenGen.hpp
++#define NUM_SHARED_MAPS 4
++
++// Refer to FileMapInfo::_current_version in filemap.hpp
++#define CURRENT_ARCHIVE_VERSION 1
++
++struct FileMapHeader {
++ int _magic; // identify file type.
++ int _version; // (from enum, above.)
++ size_t _alignment; // how shared archive should be aligned
++
++ struct space_info {
++ int _file_offset; // sizeof(this) rounded to vm page size
++ char* _base; // copy-on-write base address
++ size_t _capacity; // for validity checking
++ size_t _used; // for setting space top on read
++
++ // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
++ // the C type matching the C++ bool type on any given platform. For
++ // Hotspot on BSD we assume the corresponding C type is char but
++ // licensees on BSD versions may need to adjust the type of these fields.
++ char _read_only; // read only space?
++ char _allow_exec; // executable code in space?
++
++ } _space[NUM_SHARED_MAPS]; // was _space[CompactingPermGenGen::n_regions];
++
++ // Ignore the rest of the FileMapHeader. We don't need those fields here.
++};
++
++static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
++ jboolean i;
++ if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
++ *pvalue = i;
++ return true;
++ } else {
++ return false;
++ }
++}
++
++static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
++ uintptr_t uip;
++ if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
++ *pvalue = uip;
++ return true;
++ } else {
++ return false;
++ }
++}
++
++// used to read strings from debuggee
++static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
++ size_t i = 0;
++ char c = ' ';
++
++ while (c != '\0') {
++ if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
++ return false;
++ if (i < size - 1)
++ buf[i] = c;
++ else // smaller buffer
++ return false;
++ i++; addr++;
++ }
++
++ buf[i] = '\0';
++ return true;
++}
++
++#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
++// mangled name of Arguments::SharedArchivePath
++#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
++
++static bool init_classsharing_workaround(struct ps_prochandle* ph) {
++ lib_info* lib = ph->libs;
++ while (lib != NULL) {
++ // we are iterating over shared objects from the core dump. look for
++ // libjvm[_g].so.
++ const char *jvm_name = 0;
++ if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
++ (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
++ char classes_jsa[PATH_MAX];
++ struct FileMapHeader header;
++ size_t n = 0;
++ int fd = -1, m = 0;
++ uintptr_t base = 0, useSharedSpacesAddr = 0;
++ uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
++ jboolean useSharedSpaces = 0;
++
++ memset(classes_jsa, 0, sizeof(classes_jsa));
++ jvm_name = lib->name;
++ useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
++ if (useSharedSpacesAddr == 0) {
++ print_debug("can't lookup 'UseSharedSpaces' flag\n");
++ return false;
++ }
++
++ // Hotspot vm types are not exported to build this library. So
++ // using equivalent type jboolean to read the value of
++ // UseSharedSpaces which is same as hotspot type "bool".
++ if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
++ print_debug("can't read the value of 'UseSharedSpaces' flag\n");
++ return false;
++ }
++
++ if ((int)useSharedSpaces == 0) {
++ print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
++ return true;
++ }
++
++ sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
++ if (sharedArchivePathAddrAddr == 0) {
++ print_debug("can't lookup shared archive path symbol\n");
++ return false;
++ }
++
++ if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
++ print_debug("can't read shared archive path pointer\n");
++ return false;
++ }
++
++ if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
++ print_debug("can't read shared archive path value\n");
++ return false;
++ }
++
++ print_debug("looking for %s\n", classes_jsa);
++ // open the class sharing archive file
++ fd = pathmap_open(classes_jsa);
++ if (fd < 0) {
++ print_debug("can't open %s!\n", classes_jsa);
++ ph->core->classes_jsa_fd = -1;
++ return false;
++ } else {
++ print_debug("opened %s\n", classes_jsa);
++ }
++
++ // read FileMapHeader from the file
++ memset(&header, 0, sizeof(struct FileMapHeader));
++ if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
++ != sizeof(struct FileMapHeader)) {
++ print_debug("can't read shared archive file map header from %s\n", classes_jsa);
++ close(fd);
++ return false;
++ }
++
++ // check file magic
++ if (header._magic != 0xf00baba2) {
++ print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
++ classes_jsa, header._magic);
++ close(fd);
++ return false;
++ }
++
++ // check version
++ if (header._version != CURRENT_ARCHIVE_VERSION) {
++ print_debug("%s has wrong shared archive file version %d, expecting %d\n",
++ classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
++ close(fd);
++ return false;
++ }
++
++ ph->core->classes_jsa_fd = fd;
++ // add read-only maps from classes[_g].jsa to the list of maps
++ for (m = 0; m < NUM_SHARED_MAPS; m++) {
++ if (header._space[m]._read_only) {
++ base = (uintptr_t) header._space[m]._base;
++ // no need to worry about the fractional pages at-the-end.
++ // possible fractional pages are handled by core_read_data.
++ add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
++ base, (size_t) header._space[m]._used);
++ print_debug("added a share archive map at 0x%lx\n", base);
++ }
++ }
++ return true;
++ }
++ lib = lib->next;
++ }
++ return true;
++}
++
++
++//---------------------------------------------------------------------------
++// functions to handle map_info
++
++// Order mappings based on virtual address. We use this function as the
++// callback for sorting the array of map_info pointers.
++static int core_cmp_mapping(const void *lhsp, const void *rhsp)
++{
++ const map_info *lhs = *((const map_info **)lhsp);
++ const map_info *rhs = *((const map_info **)rhsp);
++
++ if (lhs->vaddr == rhs->vaddr)
++ return (0);
++
++ return (lhs->vaddr < rhs->vaddr ? -1 : 1);
++}
++
++// we sort map_info by starting virtual address so that we can do
++// binary search to read from an address.
++static bool sort_map_array(struct ps_prochandle* ph) {
++ size_t num_maps = ph->core->num_maps;
++ map_info* map = ph->core->maps;
++ int i = 0;
++
++ // allocate map_array
++ map_info** array;
++ if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
++ print_debug("can't allocate memory for map array\n");
++ return false;
++ }
++
++ // add maps to array
++ while (map) {
++ array[i] = map;
++ i++;
++ map = map->next;
++ }
++
++ // sort is called twice. If this is second time, clear map array
++ if (ph->core->map_array) free(ph->core->map_array);
++ ph->core->map_array = array;
++ // sort the map_info array by base virtual address.
++ qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
++ core_cmp_mapping);
++
++ // print map
++ if (is_debug()) {
++ int j = 0;
++ print_debug("---- sorted virtual address map ----\n");
++ for (j = 0; j < ph->core->num_maps; j++) {
++ print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
++ ph->core->map_array[j]->memsz);
++ }
++ }
++
++ return true;
++}
++
++#ifndef MIN
++#define MIN(x, y) (((x) < (y))? (x): (y))
++#endif
++
++static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
++ ssize_t resid = size;
++ int page_size=sysconf(_SC_PAGE_SIZE);
++ while (resid != 0) {
++ map_info *mp = core_lookup(ph, addr);
++ uintptr_t mapoff;
++ ssize_t len, rem;
++ off_t off;
++ int fd;
++
++ if (mp == NULL)
++ break; /* No mapping for this address */
++
++ fd = mp->fd;
++ mapoff = addr - mp->vaddr;
++ len = MIN(resid, mp->memsz - mapoff);
++ off = mp->offset + mapoff;
++
++ if ((len = pread(fd, buf, len, off)) <= 0)
++ break;
++
++ resid -= len;
++ addr += len;
++ buf = (char *)buf + len;
++
++ // mappings always start at page boundary. But, may end in fractional
++ // page. fill zeros for possible fractional page at the end of a mapping.
++ rem = mp->memsz % page_size;
++ if (rem > 0) {
++ rem = page_size - rem;
++ len = MIN(resid, rem);
++ resid -= len;
++ addr += len;
++ // we are not assuming 'buf' to be zero initialized.
++ memset(buf, 0, len);
++ buf += len;
++ }
++ }
++
++ if (resid) {
++ print_debug("core read failed for %d byte(s) @ 0x%lx (%d more bytes)\n",
++ size, addr, resid);
++ return false;
++ } else {
++ return true;
++ }
++}
++
++// null implementation for write
++static bool core_write_data(struct ps_prochandle* ph,
++ uintptr_t addr, const char *buf , size_t size) {
++ return false;
++}
++
++static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
++ struct reg* regs) {
++ // for core we have cached the lwp regs from NOTE section
++ thread_info* thr = ph->threads;
++ while (thr) {
++ if (thr->lwp_id == lwp_id) {
++ memcpy(regs, &thr->regs, sizeof(struct reg));
++ return true;
++ }
++ thr = thr->next;
++ }
++ return false;
++}
++
++static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
++ print_debug("core_get_lwp_info not implemented\n");
++ return false;
++}
++
++static ps_prochandle_ops core_ops = {
++ .release= core_release,
++ .p_pread= core_read_data,
++ .p_pwrite= core_write_data,
++ .get_lwp_regs= core_get_lwp_regs,
++ .get_lwp_info= core_get_lwp_info
++};
++
++// read regs and create thread from NT_PRSTATUS entries from core file
++static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
++ // we have to read prstatus_t from buf
++ // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
++ prstatus_t* prstat = (prstatus_t*) buf;
++ thread_info* newthr;
++ print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
++ // we set pthread_t to -1 for core dump
++ if((newthr = add_thread_info(ph, (pthread_t) -1, prstat->pr_pid)) == NULL)
++ return false;
++
++ // copy regs
++ memcpy(&newthr->regs, &prstat->pr_reg, sizeof(struct reg));
++
++ if (is_debug()) {
++ print_debug("integer regset\n");
++#ifdef i386
++ // print the regset
++ print_debug("\teax = 0x%x\n", newthr->regs.r_eax);
++ print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx);
++ print_debug("\tecx = 0x%x\n", newthr->regs.r_ecx);
++ print_debug("\tedx = 0x%x\n", newthr->regs.r_edx);
++ print_debug("\tesp = 0x%x\n", newthr->regs.r_esp);
++ print_debug("\tebp = 0x%x\n", newthr->regs.r_ebp);
++ print_debug("\tesi = 0x%x\n", newthr->regs.r_esi);
++ print_debug("\tedi = 0x%x\n", newthr->regs.r_edi);
++ print_debug("\teip = 0x%x\n", newthr->regs.r_eip);
++#endif
++
++#if defined(amd64) || defined(x86_64)
++ // print the regset
++ print_debug("\tr15 = 0x%lx\n", newthr->regs.r_r15);
++ print_debug("\tr14 = 0x%lx\n", newthr->regs.r_r14);
++ print_debug("\tr13 = 0x%lx\n", newthr->regs.r_r13);
++ print_debug("\tr12 = 0x%lx\n", newthr->regs.r_r12);
++ print_debug("\trbp = 0x%lx\n", newthr->regs.r_rbp);
++ print_debug("\trbx = 0x%lx\n", newthr->regs.r_rbx);
++ print_debug("\tr11 = 0x%lx\n", newthr->regs.r_r11);
++ print_debug("\tr10 = 0x%lx\n", newthr->regs.r_r10);
++ print_debug("\tr9 = 0x%lx\n", newthr->regs.r_r9);
++ print_debug("\tr8 = 0x%lx\n", newthr->regs.r_r8);
++ print_debug("\trax = 0x%lx\n", newthr->regs.r_rax);
++ print_debug("\trcx = 0x%lx\n", newthr->regs.r_rcx);
++ print_debug("\trdx = 0x%lx\n", newthr->regs.r_rdx);
++ print_debug("\trsi = 0x%lx\n", newthr->regs.r_rsi);
++ print_debug("\trdi = 0x%lx\n", newthr->regs.r_rdi);
++ //print_debug("\torig_rax = 0x%lx\n", newthr->regs.orig_rax);
++ print_debug("\trip = 0x%lx\n", newthr->regs.r_rip);
++ print_debug("\tcs = 0x%lx\n", newthr->regs.r_cs);
++ //print_debug("\teflags = 0x%lx\n", newthr->regs.eflags);
++ print_debug("\trsp = 0x%lx\n", newthr->regs.r_rsp);
++ print_debug("\tss = 0x%lx\n", newthr->regs.r_ss);
++ //print_debug("\tfs_base = 0x%lx\n", newthr->regs.fs_base);
++ //print_debug("\tgs_base = 0x%lx\n", newthr->regs.gs_base);
++ //print_debug("\tds = 0x%lx\n", newthr->regs.ds);
++ //print_debug("\tes = 0x%lx\n", newthr->regs.es);
++ //print_debug("\tfs = 0x%lx\n", newthr->regs.fs);
++ //print_debug("\tgs = 0x%lx\n", newthr->regs.gs);
++#endif
++ }
++
++ return true;
++}
++
++#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
++
++// read NT_PRSTATUS entries from core NOTE segment
++static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) {
++ char* buf = NULL;
++ char* p = NULL;
++ size_t size = note_phdr->p_filesz;
++
++ // we are interested in just prstatus entries. we will ignore the rest.
++ // Advance the seek pointer to the start of the PT_NOTE data
++ if (lseek(ph->core->core_fd, note_phdr->p_offset, SEEK_SET) == (off_t)-1) {
++ print_debug("failed to lseek to PT_NOTE data\n");
++ return false;
++ }
++
++ // Now process the PT_NOTE structures. Each one is preceded by
++ // an Elf{32/64}_Nhdr structure describing its type and size.
++ if ( (buf = (char*) malloc(size)) == NULL) {
++ print_debug("can't allocate memory for reading core notes\n");
++ goto err;
++ }
++
++ // read notes into buffer
++ if (read(ph->core->core_fd, buf, size) != size) {
++ print_debug("failed to read notes, core file must have been truncated\n");
++ goto err;
++ }
++
++ p = buf;
++ while (p < buf + size) {
++ ELF_NHDR* notep = (ELF_NHDR*) p;
++ char* descdata = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
++ print_debug("Note header with n_type = %d and n_descsz = %u\n",
++ notep->n_type, notep->n_descsz);
++
++ if (notep->n_type == NT_PRSTATUS) {
++ if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
++ return false;
++ }
++ p = descdata + ROUNDUP(notep->n_descsz, 4);
++ }
++
++ free(buf);
++ return true;
++
++err:
++ if (buf) free(buf);
++ return false;
++}
++
++// read all segments from core file
++static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) {
++ int i = 0;
++ ELF_PHDR* phbuf = NULL;
++ ELF_PHDR* core_php = NULL;
++
++ if ((phbuf = read_program_header_table(ph->core->core_fd, core_ehdr)) == NULL)
++ return false;
++
++ /*
++ * Now iterate through the program headers in the core file.
++ * We're interested in two types of Phdrs: PT_NOTE (which
++ * contains a set of saved /proc structures), and PT_LOAD (which
++ * represents a memory mapping from the process's address space).
++ *
++ * Difference b/w Solaris PT_NOTE and BSD PT_NOTE:
++ *
++ * In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
++ * contains /proc structs in the pre-2.6 unstructured /proc format. the last
++ * PT_NOTE has data in new /proc format.
++ *
++ * In Solaris, there is only one pstatus (process status). pstatus contains
++ * integer register set among other stuff. For each LWP, we have one lwpstatus
++ * entry that has integer regset for that LWP.
++ *
++ * Linux threads are actually 'clone'd processes. To support core analysis
++ * of "multithreaded" process, Linux creates more than one pstatus (called
++ * "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
++ * "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
++ * function "elf_core_dump".
++ */
++
++ for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
++ switch (core_php->p_type) {
++ case PT_NOTE:
++ if (core_handle_note(ph, core_php) != true) goto err;
++ break;
++
++ case PT_LOAD: {
++ if (core_php->p_filesz != 0) {
++ if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
++ core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
++ }
++ break;
++ }
++ }
++
++ core_php++;
++ }
++
++ free(phbuf);
++ return true;
++err:
++ free(phbuf);
++ return false;
++}
++
++// read segments of a shared object
++static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
++ int i = 0;
++ ELF_PHDR* phbuf;
++ ELF_PHDR* lib_php = NULL;
++
++ if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
++ return false;
++
++ // we want to process only PT_LOAD segments that are not writable.
++ // i.e., text segments. The read/write/exec (data) segments would
++ // have been already added from core file segments.
++ for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
++ if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
++ if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
++ goto err;
++ }
++ lib_php++;
++ }
++
++ free(phbuf);
++ return true;
++err:
++ free(phbuf);
++ return false;
++}
++
++// process segments from interpreter (ld-elf.so.1)
++static bool read_interp_segments(struct ps_prochandle* ph) {
++ ELF_EHDR interp_ehdr;
++
++ if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
++ print_debug("interpreter is not a valid ELF file\n");
++ return false;
++ }
++
++ if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
++ print_debug("can't read segments of interpreter\n");
++ return false;
++ }
++
++ return true;
++}
++
++// process segments of a a.out
++static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
++ int i = 0;
++ ELF_PHDR* phbuf = NULL;
++ ELF_PHDR* exec_php = NULL;
++
++ if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
++ return false;
++
++ for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
++ switch (exec_php->p_type) {
++
++ // add mappings for PT_LOAD segments
++ case PT_LOAD: {
++ // add only non-writable segments of non-zero filesz
++ if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
++ if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
++ }
++ break;
++ }
++
++ // read the interpreter and it's segments
++ case PT_INTERP: {
++ char interp_name[BUF_SIZE];
++
++ pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
++ print_debug("ELF interpreter %s\n", interp_name);
++ // read interpreter segments as well
++ if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
++ print_debug("can't open runtime loader\n");
++ goto err;
++ }
++ break;
++ }
++
++ // from PT_DYNAMIC we want to read address of first link_map addr
++ case PT_DYNAMIC: {
++ ph->core->dynamic_addr = exec_php->p_vaddr;
++ print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
++ break;
++ }
++
++ } // switch
++ exec_php++;
++ } // for
++
++ free(phbuf);
++ return true;
++err:
++ free(phbuf);
++ return false;
++}
++
++
++#define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug, r_map)
++#define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase)
++#define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr)
++#define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name)
++#define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next)
++
++// read shared library info from runtime linker's data structures.
++// This work is done by librtlb_db in Solaris
++static bool read_shared_lib_info(struct ps_prochandle* ph) {
++ uintptr_t addr = ph->core->dynamic_addr;
++ uintptr_t debug_base;
++ uintptr_t first_link_map_addr;
++ uintptr_t ld_base_addr;
++ uintptr_t link_map_addr;
++ uintptr_t lib_base_diff;
++ uintptr_t lib_base;
++ uintptr_t lib_name_addr;
++ char lib_name[BUF_SIZE];
++ ELF_DYN dyn;
++ ELF_EHDR elf_ehdr;
++ int lib_fd;
++
++ // _DYNAMIC has information of the form
++ // [tag] [data] [tag] [data] .....
++ // Both tag and data are pointer sized.
++ // We look for dynamic info with DT_DEBUG. This has shared object info.
++ // refer to struct r_debug in link.h
++
++ dyn.d_tag = DT_NULL;
++ while (dyn.d_tag != DT_DEBUG) {
++ if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
++ print_debug("can't read debug info from _DYNAMIC\n");
++ return false;
++ }
++ addr += sizeof(ELF_DYN);
++ }
++
++ // we have got Dyn entry with DT_DEBUG
++ debug_base = dyn.d_un.d_ptr;
++ // at debug_base we have struct r_debug. This has first link map in r_map field
++ if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
++ &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
++ print_debug("can't read first link map address\n");
++ return false;
++ }
++
++ // read ld_base address from struct r_debug
++ // XXX: There is no r_ldbase member on BSD
++/*
++ if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
++ sizeof(uintptr_t)) != PS_OK) {
++ print_debug("can't read ld base address\n");
++ return false;
++ }
++ ph->core->ld_base_addr = ld_base_addr;
++*/
++ ph->core->ld_base_addr = 0;
++
++ print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
++
++ // now read segments from interp (i.e ld-elf.so.1)
++ if (read_interp_segments(ph) != true)
++ return false;
++
++ // after adding interpreter (ld.so) mappings sort again
++ if (sort_map_array(ph) != true)
++ return false;
++
++ print_debug("first link map is at 0x%lx\n", first_link_map_addr);
++
++ link_map_addr = first_link_map_addr;
++ while (link_map_addr != 0) {
++ // read library base address of the .so. Note that even though <sys/link.h> calls
++ // link_map->l_addr as "base address", this is * not * really base virtual
++ // address of the shared object. This is actually the difference b/w the virtual
++ // address mentioned in shared object and the actual virtual base where runtime
++ // linker loaded it. We use "base diff" in read_lib_segments call below.
++
++ if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
++ &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
++ print_debug("can't read shared object base address diff\n");
++ return false;
++ }
++
++ // read address of the name
++ if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
++ &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
++ print_debug("can't read address of shared object name\n");
++ return false;
++ }
++
++ // read name of the shared object
++ if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
++ print_debug("can't read shared object name\n");
++ return false;
++ }
++
++ if (lib_name[0] != '\0') {
++ // ignore empty lib names
++ lib_fd = pathmap_open(lib_name);
++
++ if (lib_fd < 0) {
++ print_debug("can't open shared object %s\n", lib_name);
++ // continue with other libraries...
++ } else {
++ if (read_elf_header(lib_fd, &elf_ehdr)) {
++ lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
++ print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
++ lib_name, lib_base, lib_base_diff);
++ // while adding library mappings we need to use "base difference".
++ if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
++ print_debug("can't read shared object's segments\n");
++ close(lib_fd);
++ return false;
++ }
++ add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
++ // Map info is added for the library (lib_name) so
++ // we need to re-sort it before calling the p_pdread.
++ if (sort_map_array(ph) != true)
++ return false;
++ } else {
++ print_debug("can't read ELF header for shared object %s\n", lib_name);
++ close(lib_fd);
++ // continue with other libraries...
++ }
++ }
++ }
++
++ // read next link_map address
++ if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
++ &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
++ print_debug("can't read next link in link_map\n");
++ return false;
++ }
++ }
++
++ return true;
++}
++
++// the one and only one exposed stuff from this file
++struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
++ ELF_EHDR core_ehdr;
++ ELF_EHDR exec_ehdr;
++
++ struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
++ if (ph == NULL) {
++ print_debug("can't allocate ps_prochandle\n");
++ return NULL;
++ }
++
++ if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
++ free(ph);
++ print_debug("can't allocate ps_prochandle\n");
++ return NULL;
++ }
++
++ // initialize ph
++ ph->ops = &core_ops;
++ ph->core->core_fd = -1;
++ ph->core->exec_fd = -1;
++ ph->core->interp_fd = -1;
++
++ // open the core file
++ if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
++ print_debug("can't open core file\n");
++ goto err;
++ }
++
++ // read core file ELF header
++ if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
++ print_debug("core file is not a valid ELF ET_CORE file\n");
++ goto err;
++ }
++
++ if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
++ print_debug("can't open executable file\n");
++ goto err;
++ }
++
++ if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
++ print_debug("executable file is not a valid ELF ET_EXEC file\n");
++ goto err;
++ }
++
++ // process core file segments
++ if (read_core_segments(ph, &core_ehdr) != true)
++ goto err;
++
++ // process exec file segments
++ if (read_exec_segments(ph, &exec_ehdr) != true)
++ goto err;
++
++ // exec file is also treated like a shared object for symbol search
++ if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
++ (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
++ goto err;
++
++ // allocate and sort maps into map_array, we need to do this
++ // here because read_shared_lib_info needs to read from debuggee
++ // address space
++ if (sort_map_array(ph) != true)
++ goto err;
++
++ if (read_shared_lib_info(ph) != true)
++ goto err;
++
++ // sort again because we have added more mappings from shared objects
++ if (sort_map_array(ph) != true)
++ goto err;
++
++ if (init_classsharing_workaround(ph) != true)
++ goto err;
++
++ return ph;
++
++err:
++ Prelease(ph);
++ return NULL;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/ps_proc.c openjdk/hotspot/agent/src/os/bsd/ps_proc.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/ps_proc.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/ps_proc.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,444 @@
++/*
++ * 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 <limits.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <sys/ptrace.h>
++#include <sys/param.h>
++#include <sys/user.h>
++#include <elf.h>
++#include <sys/elf_common.h>
++#include <sys/link_elf.h>
++#include <libutil.h>
++#include "libproc_impl.h"
++#include "elfmacros.h"
++
++// This file has the libproc implementation specific to live process
++// For core files, refer to ps_core.c
++
++static inline uintptr_t align(uintptr_t ptr, size_t size) {
++ return (ptr & ~(size - 1));
++}
++
++// ---------------------------------------------
++// ptrace functions
++// ---------------------------------------------
++
++// read "size" bytes of data from "addr" within the target process.
++// unlike the standard ptrace() function, process_read_data() can handle
++// unaligned address - alignment check, if required, should be done
++// before calling process_read_data.
++
++static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
++ int rslt;
++ size_t i, words;
++ uintptr_t end_addr = addr + size;
++ uintptr_t aligned_addr = align(addr, sizeof(int));
++
++ if (aligned_addr != addr) {
++ char *ptr = (char *)&rslt;
++ errno = 0;
++ rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
++ if (errno) {
++ print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
++ return false;
++ }
++ for (; aligned_addr != addr; aligned_addr++, ptr++);
++ for (; ((intptr_t)aligned_addr % sizeof(int)) && aligned_addr < end_addr;
++ aligned_addr++)
++ *(buf++) = *(ptr++);
++ }
++
++ words = (end_addr - aligned_addr) / sizeof(int);
++
++ // assert((intptr_t)aligned_addr % sizeof(int) == 0);
++ for (i = 0; i < words; i++) {
++ errno = 0;
++ rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
++ if (errno) {
++ print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
++ return false;
++ }
++ *(int *)buf = rslt;
++ buf += sizeof(int);
++ aligned_addr += sizeof(int);
++ }
++
++ if (aligned_addr != end_addr) {
++ char *ptr = (char *)&rslt;
++ errno = 0;
++ rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
++ if (errno) {
++ print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
++ return false;
++ }
++ for (; aligned_addr != end_addr; aligned_addr++)
++ *(buf++) = *(ptr++);
++ }
++ return true;
++}
++
++// null implementation for write
++static bool process_write_data(struct ps_prochandle* ph,
++ uintptr_t addr, const char *buf , size_t size) {
++ return false;
++}
++
++// "user" should be a pointer to a reg
++static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct reg *user) {
++ // we have already attached to all thread 'pid's, just use ptrace call
++ // to get regset now. Note that we don't cache regset upfront for processes.
++ if (ptrace(PT_GETREGS, pid, (caddr_t) user, 0) < 0) {
++ print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp %d\n", pid);
++ return false;
++ }
++ return true;
++}
++
++// fill in ptrace_lwpinfo for lid
++static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
++ errno = 0;
++ ptrace(PT_LWPINFO, lwp_id, linfo, sizeof(struct ptrace_lwpinfo));
++
++ return (errno == 0)? true: false;
++}
++
++// attach to a process/thread specified by "pid"
++static bool ptrace_attach(pid_t pid) {
++ if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
++ print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
++ return false;
++ } else {
++ int ret;
++ int status;
++ do {
++ // Wait for debuggee to stop.
++ ret = waitpid(pid, &status, 0);
++ if (ret >= 0) {
++ if (WIFSTOPPED(status)) {
++ // Debuggee stopped.
++ return true;
++ } else {
++ print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
++ return false;
++ }
++ } else {
++ switch (errno) {
++ case EINTR:
++ continue;
++ break;
++ case ECHILD:
++ print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
++ break;
++ case EINVAL:
++ print_debug("waitpid() failed. Invalid options argument.\n");
++ break;
++ default:
++ print_debug("waitpid() failed. Unexpected error %d\n",errno);
++ }
++ return false;
++ }
++ } while(true);
++ }
++}
++
++// -------------------------------------------------------
++// functions for obtaining library information
++// -------------------------------------------------------
++
++// callback for read_thread_info
++static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
++ return add_thread_info(ph, pthread_id, lwp_id) != NULL;
++}
++
++#if defined(__FreeBSD__) && __FreeBSD_version < 701000
++/*
++ * TEXT_START_ADDR from binutils/ld/emulparams/<arch_spec>.sh
++ * Not the most robust but good enough.
++ */
++
++#if defined(amd64) || defined(x86_64)
++#define TEXT_START_ADDR 0x400000
++#elif defined(i386)
++#define TEXT_START_ADDR 0x8048000
++#else
++#error TEXT_START_ADDR not defined
++#endif
++
++#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
++
++uintptr_t linkmap_addr(struct ps_prochandle *ph) {
++ uintptr_t ehdr_addr, phdr_addr, dyn_addr, dmap_addr, lmap_addr;
++ ELF_EHDR ehdr;
++ ELF_PHDR *phdrs, *phdr;
++ ELF_DYN *dyns, *dyn;
++ struct r_debug dmap;
++ unsigned long hdrs_size;
++ unsigned int i;
++
++ /* read ELF_EHDR at TEXT_START_ADDR and validate */
++
++ ehdr_addr = (uintptr_t)TEXT_START_ADDR;
++
++ if (process_read_data(ph, ehdr_addr, (char *)&ehdr, sizeof(ehdr)) != true) {
++ print_debug("process_read_data failed for ehdr_addr %p\n", ehdr_addr);
++ return (0);
++ }
++
++ if (!IS_ELF(ehdr) ||
++ ehdr.e_ident[EI_CLASS] != ELF_TARG_CLASS ||
++ ehdr.e_ident[EI_DATA] != ELF_TARG_DATA ||
++ ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
++ ehdr.e_phentsize != sizeof(ELF_PHDR) ||
++ ehdr.e_version != ELF_TARG_VER ||
++ ehdr.e_machine != ELF_TARG_MACH) {
++ print_debug("not an ELF_EHDR at %p\n", ehdr_addr);
++ return (0);
++ }
++
++ /* allocate space for all ELF_PHDR's and read */
++
++ phdr_addr = ehdr_addr + ehdr.e_phoff;
++ hdrs_size = ehdr.e_phnum * sizeof(ELF_PHDR);
++
++ if ((phdrs = malloc(hdrs_size)) == NULL)
++ return (0);
++
++ if (process_read_data(ph, phdr_addr, (char *)phdrs, hdrs_size) != true) {
++ print_debug("process_read_data failed for phdr_addr %p\n", phdr_addr);
++ return (0);
++ }
++
++ /* find PT_DYNAMIC section */
++
++ for (i = 0, phdr = phdrs; i < ehdr.e_phnum; i++, phdr++) {
++ if (phdr->p_type == PT_DYNAMIC)
++ break;
++ }
++
++ if (i >= ehdr.e_phnum) {
++ print_debug("PT_DYNAMIC section not found!\n");
++ free(phdrs);
++ return (0);
++ }
++
++ /* allocate space and read in ELF_DYN headers */
++
++ dyn_addr = phdr->p_vaddr;
++ hdrs_size = phdr->p_memsz;
++ free(phdrs);
++
++ if ((dyns = malloc(hdrs_size)) == NULL)
++ return (0);
++
++ if (process_read_data(ph, dyn_addr, (char *)dyns, hdrs_size) != true) {
++ print_debug("process_read_data failed for dyn_addr %p\n", dyn_addr);
++ free(dyns);
++ return (0);
++ }
++
++ /* find DT_DEBUG */
++
++ dyn = dyns;
++ while (dyn->d_tag != DT_DEBUG && dyn->d_tag != DT_NULL) {
++ dyn++;
++ }
++
++ if (dyn->d_tag != DT_DEBUG) {
++ print_debug("failed to find DT_DEBUG\n");
++ free(dyns);
++ return (0);
++ }
++
++ /* read struct r_debug into dmap */
++
++ dmap_addr = (uintptr_t)dyn->d_un.d_ptr;
++ free(dyns);
++
++ if (process_read_data(ph, dmap_addr, (char *)&dmap, sizeof(dmap)) != true) {
++ print_debug("process_read_data failed for dmap_addr %p\n", dmap_addr);
++ return (0);
++ }
++
++ lmap_addr = (uintptr_t)dmap.r_map;
++
++ return (lmap_addr);
++}
++#endif // __FreeBSD__ && __FreeBSD_version < 701000
++
++static bool read_lib_info(struct ps_prochandle* ph) {
++#if defined(__FreeBSD__) && __FreeBSD_version >= 701000
++ struct kinfo_vmentry *freep, *kve;
++ int i, cnt;
++
++ freep = kinfo_getvmmap(ph->pid, &cnt);
++ if (freep == NULL) {
++ print_debug("can't get vm map for pid\n", ph->pid);
++ return false;
++ }
++
++ for (i = 0; i < cnt; i++) {
++ kve = &freep[i];
++ if ((kve->kve_flags & KVME_FLAG_COW) &&
++ kve->kve_path != NULL &&
++ strlen(kve->kve_path) > 0) {
++
++ if (find_lib(ph, kve->kve_path) == false) {
++ lib_info* lib;
++ if ((lib = add_lib_info(ph, kve->kve_path,
++ (uintptr_t) kve->kve_start)) == NULL)
++ continue; // ignore, add_lib_info prints error
++
++ // we don't need to keep the library open, symtab is already
++ // built. Only for core dump we need to keep the fd open.
++ close(lib->fd);
++ lib->fd = -1;
++ }
++ }
++ }
++
++ free(freep);
++
++ return true;
++#else
++ char *l_name;
++ struct link_map *lmap;
++ uintptr_t lmap_addr;
++
++ if ((l_name = malloc(BUF_SIZE)) == NULL)
++ return false;
++
++ if ((lmap = malloc(sizeof(*lmap))) == NULL) {
++ free(l_name);
++ return false;
++ }
++
++ lmap_addr = linkmap_addr(ph);
++
++ if (lmap_addr == 0) {
++ free(l_name);
++ free(lmap);
++ return false;
++ }
++
++ do {
++ if (process_read_data(ph, lmap_addr, (char *)lmap, sizeof(*lmap)) != true) {
++ print_debug("process_read_data failed for lmap_addr %p\n", lmap_addr);
++ free (l_name);
++ free (lmap);
++ return false;
++ }
++
++ if (process_read_data(ph, (uintptr_t)lmap->l_name, l_name,
++ BUF_SIZE) != true) {
++ print_debug("process_read_data failed for lmap->l_name %p\n",
++ lmap->l_name);
++ free (l_name);
++ free (lmap);
++ return false;
++ }
++
++ if (find_lib(ph, l_name) == false) {
++ lib_info* lib;
++ if ((lib = add_lib_info(ph, l_name,
++ (uintptr_t) lmap->l_addr)) == NULL)
++ continue; // ignore, add_lib_info prints error
++
++ // we don't need to keep the library open, symtab is already
++ // built. Only for core dump we need to keep the fd open.
++ close(lib->fd);
++ lib->fd = -1;
++ }
++ lmap_addr = (uintptr_t)lmap->l_next;
++ } while (lmap->l_next != NULL);
++
++ free (l_name);
++ free (lmap);
++
++ return true;
++#endif
++}
++
++// detach a given pid
++static bool ptrace_detach(pid_t pid) {
++ if (pid && ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) {
++ print_debug("ptrace(PTRACE_DETACH, ..) failed for %d\n", pid);
++ return false;
++ } else {
++ return true;
++ }
++}
++
++static void process_cleanup(struct ps_prochandle* ph) {
++ ptrace_detach(ph->pid);
++}
++
++static ps_prochandle_ops process_ops = {
++ .release= process_cleanup,
++ .p_pread= process_read_data,
++ .p_pwrite= process_write_data,
++ .get_lwp_regs= process_get_lwp_regs,
++ .get_lwp_info= process_get_lwp_info
++};
++
++// attach to the process. One and only one exposed stuff
++struct ps_prochandle* Pgrab(pid_t pid) {
++ struct ps_prochandle* ph = NULL;
++ thread_info* thr = NULL;
++
++ if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
++ print_debug("can't allocate memory for ps_prochandle\n");
++ return NULL;
++ }
++
++ if (ptrace_attach(pid) != true) {
++ free(ph);
++ return NULL;
++ }
++
++ // initialize ps_prochandle
++ ph->pid = pid;
++
++ // initialize vtable
++ ph->ops = &process_ops;
++
++ // read library info and symbol tables, must do this before attaching threads,
++ // as the symbols in the pthread library will be used to figure out
++ // the list of threads within the same process.
++ if (read_lib_info(ph) != true) {
++ ptrace_detach(pid);
++ free(ph);
++ return NULL;
++ }
++
++ // read thread info
++ read_thread_info(ph, add_new_thread);
++
++ return ph;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/salibelf.c openjdk/hotspot/agent/src/os/bsd/salibelf.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/salibelf.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/salibelf.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (c) 2003, 2006, 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 "salibelf.h"
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++
++extern void print_debug(const char*,...);
++
++// ELF file parsing helpers. Note that we do *not* use libelf here.
++int read_elf_header(int fd, ELF_EHDR* ehdr) {
++ if (pread(fd, ehdr, sizeof (ELF_EHDR), 0) != sizeof (ELF_EHDR) ||
++ memcmp(&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
++ ehdr->e_version != EV_CURRENT) {
++ return 0;
++ }
++ return 1;
++}
++
++bool is_elf_file(int fd) {
++ ELF_EHDR ehdr;
++ return read_elf_header(fd, &ehdr);
++}
++
++// read program header table of an ELF file
++ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr) {
++ ELF_PHDR* phbuf = 0;
++ // allocate memory for program header table
++ size_t nbytes = hdr->e_phnum * hdr->e_phentsize;
++
++ if ((phbuf = (ELF_PHDR*) malloc(nbytes)) == NULL) {
++ print_debug("can't allocate memory for reading program header table\n");
++ return NULL;
++ }
++
++ if (pread(fd, phbuf, nbytes, hdr->e_phoff) != nbytes) {
++ print_debug("ELF file is truncated! can't read program header table\n");
++ free(phbuf);
++ return NULL;
++ }
++
++ return phbuf;
++}
++
++// read section header table of an ELF file
++ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr) {
++ ELF_SHDR* shbuf = 0;
++ // allocate memory for section header table
++ size_t nbytes = hdr->e_shnum * hdr->e_shentsize;
++
++ if ((shbuf = (ELF_SHDR*) malloc(nbytes)) == NULL) {
++ print_debug("can't allocate memory for reading section header table\n");
++ return NULL;
++ }
++
++ if (pread(fd, shbuf, nbytes, hdr->e_shoff) != nbytes) {
++ print_debug("ELF file is truncated! can't read section header table\n");
++ free(shbuf);
++ return NULL;
++ }
++
++ return shbuf;
++}
++
++// read a particular section's data
++void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr) {
++ void *buf = NULL;
++ if (shdr->sh_type == SHT_NOBITS || shdr->sh_size == 0) {
++ return buf;
++ }
++ if ((buf = calloc(shdr->sh_size, 1)) == NULL) {
++ print_debug("can't allocate memory for reading section data\n");
++ return NULL;
++ }
++ if (pread(fd, buf, shdr->sh_size, shdr->sh_offset) != shdr->sh_size) {
++ free(buf);
++ print_debug("section data read failed\n");
++ return NULL;
++ }
++ return buf;
++}
++
++uintptr_t find_base_address(int fd, ELF_EHDR* ehdr) {
++ uintptr_t baseaddr = (uintptr_t)-1;
++ int cnt;
++ ELF_PHDR *phbuf, *phdr;
++
++ // read program header table
++ if ((phbuf = read_program_header_table(fd, ehdr)) == NULL) {
++ goto quit;
++ }
++
++ // the base address of a shared object is the lowest vaddr of
++ // its loadable segments (PT_LOAD)
++ for (phdr = phbuf, cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
++ if (phdr->p_type == PT_LOAD && phdr->p_vaddr < baseaddr) {
++ baseaddr = phdr->p_vaddr;
++ }
++ }
++
++quit:
++ if (phbuf) free(phbuf);
++ return baseaddr;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/salibelf.h openjdk/hotspot/agent/src/os/bsd/salibelf.h
+--- openjdk.orig/hotspot/agent/src/os/bsd/salibelf.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/salibelf.h 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2003, 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.
++ *
++ */
++
++#ifndef _SALIBELF_H_
++#define _SALIBELF_H_
++
++#include <elf.h>
++#include "elfmacros.h"
++#include "libproc_impl.h"
++
++// read ELF file header.
++int read_elf_header(int fd, ELF_EHDR* ehdr);
++
++// is given file descriptor corresponds to an ELF file?
++bool is_elf_file(int fd);
++
++// read program header table of an ELF file. caller has to
++// free the result pointer after use. NULL on failure.
++ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr);
++
++// read section header table of an ELF file. caller has to
++// free the result pointer after use. NULL on failure.
++ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr);
++
++// read a particular section's data. caller has to free the
++// result pointer after use. NULL on failure.
++void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr);
++
++// find the base address at which the library wants to load itself
++uintptr_t find_base_address(int fd, ELF_EHDR* ehdr);
++#endif /* _SALIBELF_H_ */
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/StubDebuggerLocal.c openjdk/hotspot/agent/src/os/bsd/StubDebuggerLocal.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/StubDebuggerLocal.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/StubDebuggerLocal.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (c) 2009, 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 <stdlib.h>
++#include <jni.h>
++
++#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);
++}
++
++/*
++ * 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) {
++}
++
++JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
++ (JNIEnv *env, jclass cls)
++{
++#ifdef _LP64
++ return 8;
++#else
++ return 4;
++#endif
++
++}
++
++/*
++ * 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) {
++
++ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
++}
++
++/*
++ * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
++ * Method: attach0
++ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
++ */
++JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
++ (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
++ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
++}
++
++/*
++ * 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) {
++}
++
++/*
++ * 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) {
++ return 0;
++}
++
++/*
++ * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
++ * Method: lookupByAddress0
++ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
++ */
++JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
++ (JNIEnv *env, jobject this_obj, jlong addr) {
++ return 0;
++}
++
++/*
++ * 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) {
++ return 0;
++}
++
++JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
++ (JNIEnv *env, jobject this_obj, jint lwp_id) {
++ return 0;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/symtab.c openjdk/hotspot/agent/src/os/bsd/symtab.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/symtab.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/symtab.c 2013-04-08 01:49:33.578321427 +0100
+@@ -0,0 +1,239 @@
++/*
++ * 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 <unistd.h>
++#include <search.h>
++#include <stdlib.h>
++#include <string.h>
++#include <db.h>
++#include <fcntl.h>
++#include "symtab.h"
++#include "salibelf.h"
++
++
++// ----------------------------------------------------
++// functions for symbol lookups
++// ----------------------------------------------------
++
++struct elf_section {
++ ELF_SHDR *c_shdr;
++ void *c_data;
++};
++
++struct elf_symbol {
++ char *name;
++ uintptr_t offset;
++ uintptr_t size;
++};
++
++typedef struct symtab {
++ char *strs;
++ size_t num_symbols;
++ struct elf_symbol *symbols;
++ DB* hash_table;
++} symtab_t;
++
++// read symbol table from given fd.
++struct symtab* build_symtab(int fd) {
++ ELF_EHDR ehdr;
++ struct symtab* symtab = NULL;
++
++ // Reading of elf header
++ struct elf_section *scn_cache = NULL;
++ int cnt = 0;
++ ELF_SHDR* shbuf = NULL;
++ ELF_SHDR* cursct = NULL;
++ ELF_PHDR* phbuf = NULL;
++ int symtab_found = 0;
++ int dynsym_found = 0;
++ uint32_t symsection = SHT_SYMTAB;
++
++ uintptr_t baseaddr = (uintptr_t)-1;
++
++ lseek(fd, (off_t)0L, SEEK_SET);
++ if (! read_elf_header(fd, &ehdr)) {
++ // not an elf
++ return NULL;
++ }
++
++ // read ELF header
++ if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
++ goto quit;
++ }
++
++ baseaddr = find_base_address(fd, &ehdr);
++
++ scn_cache = calloc(ehdr.e_shnum, sizeof(*scn_cache));
++ if (scn_cache == NULL) {
++ goto quit;
++ }
++
++ for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
++ scn_cache[cnt].c_shdr = cursct;
++ if (cursct->sh_type == SHT_SYMTAB ||
++ cursct->sh_type == SHT_STRTAB ||
++ cursct->sh_type == SHT_DYNSYM) {
++ if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
++ goto quit;
++ }
++ }
++
++ if (cursct->sh_type == SHT_SYMTAB)
++ symtab_found++;
++
++ if (cursct->sh_type == SHT_DYNSYM)
++ dynsym_found++;
++
++ cursct++;
++ }
++
++ if (!symtab_found && dynsym_found)
++ symsection = SHT_DYNSYM;
++
++ for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
++ ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
++
++ if (shdr->sh_type == symsection) {
++ ELF_SYM *syms;
++ int j, n, rslt;
++ size_t size;
++
++ // FIXME: there could be multiple data buffers associated with the
++ // same ELF section. Here we can handle only one buffer. See man page
++ // for elf_getdata on Solaris.
++
++ // guarantee(symtab == NULL, "multiple symtab");
++ symtab = calloc(1, sizeof(*symtab));
++ if (symtab == NULL) {
++ goto quit;
++ }
++ // the symbol table
++ syms = (ELF_SYM *)scn_cache[cnt].c_data;
++
++ // number of symbols
++ n = shdr->sh_size / shdr->sh_entsize;
++
++ // create hash table, we use berkeley db to
++ // manipulate the hash table.
++ symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL);
++ // guarantee(symtab->hash_table, "unexpected failure: dbopen");
++
++ // 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
++ // string table index. we make a copy of the string table so the
++ // strings will not be destroyed by elf_end.
++ size = scn_cache[shdr->sh_link].c_shdr->sh_size;
++ symtab->strs = malloc(size);
++ 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));
++
++ // copy symbols info our symtab and enter them info the hash table
++ for (j = 0; j < n; j++, syms++) {
++ DBT key, value;
++ char *sym_name = symtab->strs + syms->st_name;
++
++ // skip non-object and non-function symbols
++ int st_type = ELF_ST_TYPE(syms->st_info);
++ if ( st_type != STT_FUNC && st_type != STT_OBJECT)
++ continue;
++ // skip empty strings and undefined symbols
++ if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
++
++ symtab->symbols[j].name = sym_name;
++ symtab->symbols[j].offset = syms->st_value - baseaddr;
++ symtab->symbols[j].size = syms->st_size;
++
++ key.data = sym_name;
++ key.size = strlen(sym_name) + 1;
++ value.data = &(symtab->symbols[j]);
++ value.size = sizeof(void *);
++ (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0);
++ }
++ }
++ }
++
++quit:
++ if (shbuf) free(shbuf);
++ if (phbuf) free(phbuf);
++ if (scn_cache) {
++ for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
++ if (scn_cache[cnt].c_data != NULL) {
++ free(scn_cache[cnt].c_data);
++ }
++ }
++ free(scn_cache);
++ }
++ return symtab;
++}
++
++void destroy_symtab(struct symtab* symtab) {
++ if (!symtab) return;
++ if (symtab->strs) free(symtab->strs);
++ if (symtab->symbols) free(symtab->symbols);
++ if (symtab->hash_table) {
++ symtab->hash_table->close(symtab->hash_table);
++ }
++ free(symtab);
++}
++
++uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
++ const char *sym_name, int *sym_size) {
++ DBT key, value;
++ int ret;
++
++ // library does not have symbol table
++ if (!symtab || !symtab->hash_table)
++ return 0;
++
++ key.data = (char*)(uintptr_t)sym_name;
++ key.size = strlen(sym_name) + 1;
++ ret = (*symtab->hash_table->get)(symtab->hash_table, &key, &value, 0);
++ if (ret == 0) {
++ struct elf_symbol *sym = value.data;
++ uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
++ if (sym_size) *sym_size = sym->size;
++ return rslt;
++ }
++
++quit:
++ return 0;
++}
++
++const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
++ uintptr_t* poffset) {
++ 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;
++ }
++ }
++ return NULL;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/symtab.h openjdk/hotspot/agent/src/os/bsd/symtab.h
+--- openjdk.orig/hotspot/agent/src/os/bsd/symtab.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/symtab.h 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,50 @@
++/*
++ * 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 _SYMTAB_H_
++#define _SYMTAB_H_
++
++#include <stdint.h>
++
++// interface to manage ELF symbol tables
++
++struct symtab;
++
++// build symbol table for a given ELF file descriptor
++struct symtab* build_symtab(int fd);
++
++// destroy the symbol table
++void destroy_symtab(struct symtab* symtab);
++
++// search for symbol in the given symbol table. Adds offset
++// to the base uintptr_t supplied. Returns NULL if not found.
++uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
++ const char *sym_name, int *sym_size);
++
++// look for nearest symbol for a given offset (not address - base
++// subtraction done by caller
++const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
++ uintptr_t* poffset);
++
++#endif /*_SYMTAB_H_*/
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/test.c openjdk/hotspot/agent/src/os/bsd/test.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/test.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/test.c 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (c) 2003, 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 <stdio.h>
++#include <stdlib.h>
++#include "libproc.h"
++
++int main(int argc, char** argv) {
++ struct ps_prochandle* ph;
++
++ init_libproc(true);
++ switch (argc) {
++ case 2: {
++ // process
++ ph = Pgrab(atoi(argv[1]));
++ break;
++ }
++
++ case 3: {
++ // core
++ ph = Pgrab_core(argv[1], argv[2]);
++ break;
++ }
++
++ default: {
++ fprintf(stderr, "usage %s <pid> or %s <exec file> <core file>\n", argv[0], argv[0]);
++ return 1;
++ }
++ }
++
++ if (ph) {
++ Prelease(ph);
++ return 0;
++ } else {
++ printf("can't connect to debuggee\n");
++ return 1;
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.types.*;
++import sun.jvm.hotspot.types.basic.*;
++
++public class BsdVtblAccess extends BasicVtblAccess {
++ private String vt;
++
++ public BsdVtblAccess(SymbolLookup symbolLookup,
++ String[] dllNames) {
++ super(symbolLookup, dllNames);
++
++ if (symbolLookup.lookup("libjvm.so", "__vt_10JavaThread") != null ||
++ symbolLookup.lookup("libjvm_g.so", "__vt_10JavaThread") != null) {
++ // old C++ ABI
++ vt = "__vt_";
++ } else {
++ // new C++ ABI
++ vt = "_ZTV";
++ }
++ }
++
++ protected String vtblSymbolForType(Type type) {
++ return vt + type.getName().length() + type;
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java 2013-04-08 01:49:33.582321490 +0100
+@@ -29,6 +29,7 @@
+ import java.rmi.*;
+ import sun.jvm.hotspot.*;
+ import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.bsd.*;
+ import sun.jvm.hotspot.debugger.proc.*;
+ import sun.jvm.hotspot.debugger.cdbg.*;
+ import sun.jvm.hotspot.debugger.windbg.*;
+@@ -514,6 +515,8 @@
+ setupDebuggerWin32();
+ } else if (os.equals("linux")) {
+ setupDebuggerLinux();
++ } else if (os.equals("bsd")) {
++ setupDebuggerBsd();
+ } else {
+ // Add support for more operating systems here
+ throw new DebuggerException("Operating system " + os + " not yet supported");
+@@ -565,6 +568,9 @@
+ } else if (os.equals("linux")) {
+ db = new HotSpotTypeDataBase(machDesc, new LinuxVtblAccess(debugger, jvmLibNames),
+ debugger, jvmLibNames);
++ } else if (os.equals("bsd")) {
++ db = new HotSpotTypeDataBase(machDesc, new BsdVtblAccess(debugger, jvmLibNames),
++ debugger, jvmLibNames);
+ } else {
+ throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess implemented yet)");
+ }
+@@ -666,6 +672,8 @@
+ setupJVMLibNamesWin32();
+ } else if (os.equals("linux")) {
+ setupJVMLibNamesLinux();
++ } else if (os.equals("bsd")) {
++ setupJVMLibNamesBsd();
+ } else {
+ throw new RuntimeException("Unknown OS type");
+ }
+@@ -744,6 +752,34 @@
+ // same as solaris
+ setupJVMLibNamesSolaris();
+ }
++
++ //
++ // BSD
++ //
++
++ private void setupDebuggerBsd() {
++ setupJVMLibNamesBsd();
++
++ if (cpu.equals("x86")) {
++ machDesc = new MachineDescriptionIntelX86();
++ } else if (cpu.equals("amd64")) {
++ machDesc = new MachineDescriptionAMD64();
++ } else {
++ throw new DebuggerException("Bsd only supported on x86/amd64");
++ }
++
++ // Note we do not use a cache for the local debugger in server
++ // mode; it will be taken care of on the client side (once remote
++ // debugging is implemented).
++
++ debugger = new BsdDebuggerLocal(machDesc, !isServer);
++ attachDebugger();
++ }
++
++ private void setupJVMLibNamesBsd() {
++ // same as solaris
++ setupJVMLibNamesSolaris();
++ }
+
+ /** Convenience routine which should be called by per-platform
+ debugger setup. Should not be called when startupMode is
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64CFrame.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64CFrame.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64CFrame.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64CFrame.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd.amd64;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.bsd.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++import sun.jvm.hotspot.debugger.cdbg.basic.*;
++
++final public class BsdAMD64CFrame extends BasicCFrame {
++ public BsdAMD64CFrame(BsdDebugger dbg, Address rbp, Address rip) {
++ super(dbg.getCDebugger());
++ this.rbp = rbp;
++ this.rip = rip;
++ this.dbg = dbg;
++ }
++
++ // override base class impl to avoid ELF parsing
++ public ClosestSymbol closestSymbolToPC() {
++ // try native lookup in debugger.
++ return dbg.lookup(dbg.getAddressValue(pc()));
++ }
++
++ public Address pc() {
++ return rip;
++ }
++
++ public Address localVariableBase() {
++ return rbp;
++ }
++
++ public CFrame sender() {
++ if (rbp == null) {
++ return null;
++ }
++
++ Address nextRBP = rbp.getAddressAt( 0 * ADDRESS_SIZE);
++ if (nextRBP == null) {
++ return null;
++ }
++ Address nextPC = rbp.getAddressAt( 1 * ADDRESS_SIZE);
++ if (nextPC == null) {
++ return null;
++ }
++ return new BsdAMD64CFrame(dbg, nextRBP, nextPC);
++ }
++
++ // package/class internals only
++ private static final int ADDRESS_SIZE = 8;
++ private Address rip;
++ private Address rbp;
++ private BsdDebugger dbg;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64ThreadContext.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64ThreadContext.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64ThreadContext.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/amd64/BsdAMD64ThreadContext.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd.amd64;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.amd64.*;
++import sun.jvm.hotspot.debugger.bsd.*;
++
++public class BsdAMD64ThreadContext extends AMD64ThreadContext {
++ private BsdDebugger debugger;
++
++ public BsdAMD64ThreadContext(BsdDebugger debugger) {
++ super();
++ this.debugger = debugger;
++ }
++
++ public void setRegisterAsAddress(int index, Address value) {
++ setRegister(index, debugger.getAddressValue(value));
++ }
++
++ public Address getRegisterAsAddress(int index) {
++ return debugger.newAddress(getRegister(index));
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,399 @@
++/*
++ * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import sun.jvm.hotspot.debugger.*;
++
++class BsdAddress implements Address {
++ protected BsdDebugger debugger;
++ protected long addr;
++
++ BsdAddress(BsdDebugger debugger, long addr) {
++ this.debugger = debugger;
++ this.addr = addr;
++ }
++
++ //
++ // Basic Java routines
++ //
++
++ public boolean equals(Object arg) {
++ if (arg == null) {
++ return false;
++ }
++
++ if (!(arg instanceof BsdAddress)) {
++ return false;
++ }
++
++ return (addr == ((BsdAddress) arg).addr);
++ }
++
++ public int hashCode() {
++ // FIXME: suggestions on a better hash code?
++ return (int) addr;
++ }
++
++ public String toString() {
++ return debugger.addressValueToString(addr);
++ }
++
++ //
++ // C/C++-related routines
++ //
++
++ public long getCIntegerAt(long offset, long numBytes, boolean isUnsigned)
++ throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readCInteger(addr + offset, numBytes, isUnsigned);
++ }
++
++ public Address getAddressAt(long offset)
++ throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readAddress(addr + offset);
++ }
++
++ public Address getCompOopAddressAt(long offset)
++ throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readCompOopAddress(addr + offset);
++ }
++
++ //
++ // Java-related routines
++ //
++
++ public boolean getJBooleanAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJBoolean(addr + offset);
++ }
++
++ public byte getJByteAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJByte(addr + offset);
++ }
++
++ public char getJCharAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJChar(addr + offset);
++ }
++
++ public double getJDoubleAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJDouble(addr + offset);
++ }
++
++ public float getJFloatAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJFloat(addr + offset);
++ }
++
++ public int getJIntAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJInt(addr + offset);
++ }
++
++ public long getJLongAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJLong(addr + offset);
++ }
++
++ public short getJShortAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
++ return debugger.readJShort(addr + offset);
++ }
++
++ public OopHandle getOopHandleAt(long offset)
++ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
++ return debugger.readOopHandle(addr + offset);
++ }
++
++ public OopHandle getCompOopHandleAt(long offset)
++ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
++ return debugger.readCompOopHandle(addr + offset);
++ }
++
++ // Mutators -- not implemented for now (FIXME)
++ public void setCIntegerAt(long offset, long numBytes, long value) {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setAddressAt(long offset, Address value) {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJBooleanAt (long offset, boolean value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJByteAt (long offset, byte value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJCharAt (long offset, char value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJDoubleAt (long offset, double value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJFloatAt (long offset, float value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJIntAt (long offset, int value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJLongAt (long offset, long value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setJShortAt (long offset, short value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++ public void setOopHandleAt (long offset, OopHandle value)
++ throws UnmappedAddressException, UnalignedAddressException {
++ throw new DebuggerException("Unimplemented");
++ }
++
++ //
++ // Arithmetic operations -- necessary evil.
++ //
++
++ public Address addOffsetTo (long offset) throws UnsupportedOperationException {
++ long value = addr + offset;
++ if (value == 0) {
++ return null;
++ }
++ return new BsdAddress(debugger, value);
++ }
++
++ public OopHandle addOffsetToAsOopHandle(long offset) throws UnsupportedOperationException {
++ long value = addr + offset;
++ if (value == 0) {
++ return null;
++ }
++ return new BsdOopHandle(debugger, value);
++ }
++
++ /** (FIXME: any signed/unsigned issues? Should this work for
++ OopHandles?) */
++ public long minus(Address arg) {
++ if (arg == null) {
++ return addr;
++ }
++ return addr - ((BsdAddress) arg).addr;
++ }
++
++ // Two's complement representation.
++ // All negative numbers are larger than positive numbers.
++ // Numbers with the same sign can be compared normally.
++ // Test harness is below in main().
++
++ public boolean lessThan (Address a) {
++ if (a == null) {
++ return false;
++ }
++ BsdAddress arg = (BsdAddress) a;
++ if ((addr >= 0) && (arg.addr < 0)) {
++ return true;
++ }
++ if ((addr < 0) && (arg.addr >= 0)) {
++ return false;
++ }
++ return (addr < arg.addr);
++ }
++
++ public boolean lessThanOrEqual (Address a) {
++ if (a == null) {
++ return false;
++ }
++ BsdAddress arg = (BsdAddress) a;
++ if ((addr >= 0) && (arg.addr < 0)) {
++ return true;
++ }
++ if ((addr < 0) && (arg.addr >= 0)) {
++ return false;
++ }
++ return (addr <= arg.addr);
++ }
++
++ public boolean greaterThan (Address a) {
++ if (a == null) {
++ return true;
++ }
++ BsdAddress arg = (BsdAddress) a;
++ if ((addr >= 0) && (arg.addr < 0)) {
++ return false;
++ }
++ if ((addr < 0) && (arg.addr >= 0)) {
++ return true;
++ }
++ return (addr > arg.addr);
++ }
++
++ public boolean greaterThanOrEqual(Address a) {
++ if (a == null) {
++ return true;
++ }
++ BsdAddress arg = (BsdAddress) a;
++ if ((addr >= 0) && (arg.addr < 0)) {
++ return false;
++ }
++ if ((addr < 0) && (arg.addr >= 0)) {
++ return true;
++ }
++ return (addr >= arg.addr);
++ }
++
++ public Address andWithMask(long mask) throws UnsupportedOperationException {
++ long value = addr & mask;
++ if (value == 0) {
++ return null;
++ }
++ return new BsdAddress(debugger, value);
++ }
++
++ public Address orWithMask(long mask) throws UnsupportedOperationException {
++ long value = addr | mask;
++ if (value == 0) {
++ return null;
++ }
++ return new BsdAddress(debugger, value);
++ }
++
++ public Address xorWithMask(long mask) throws UnsupportedOperationException {
++ long value = addr ^ mask;
++ if (value == 0) {
++ return null;
++ }
++ return new BsdAddress(debugger, value);
++ }
++
++
++ //--------------------------------------------------------------------------------
++ // Internals only below this point
++ //
++
++ long getValue() {
++ return addr;
++ }
++
++
++ private static void check(boolean arg, String failMessage) {
++ if (!arg) {
++ System.err.println(failMessage + ": FAILED");
++ System.exit(1);
++ }
++ }
++
++ // Test harness
++ public static void main(String[] args) {
++ // p/n indicates whether the interior address is really positive
++ // or negative. In unsigned terms, p1 < p2 < n1 < n2.
++
++ BsdAddress p1 = new BsdAddress(null, 0x7FFFFFFFFFFFFFF0L);
++ BsdAddress p2 = (BsdAddress) p1.addOffsetTo(10);
++ BsdAddress n1 = (BsdAddress) p2.addOffsetTo(10);
++ BsdAddress n2 = (BsdAddress) n1.addOffsetTo(10);
++
++ // lessThan positive tests
++ check(p1.lessThan(p2), "lessThan 1");
++ check(p1.lessThan(n1), "lessThan 2");
++ check(p1.lessThan(n2), "lessThan 3");
++ check(p2.lessThan(n1), "lessThan 4");
++ check(p2.lessThan(n2), "lessThan 5");
++ check(n1.lessThan(n2), "lessThan 6");
++
++ // lessThan negative tests
++ check(!p1.lessThan(p1), "lessThan 7");
++ check(!p2.lessThan(p2), "lessThan 8");
++ check(!n1.lessThan(n1), "lessThan 9");
++ check(!n2.lessThan(n2), "lessThan 10");
++
++ check(!p2.lessThan(p1), "lessThan 11");
++ check(!n1.lessThan(p1), "lessThan 12");
++ check(!n2.lessThan(p1), "lessThan 13");
++ check(!n1.lessThan(p2), "lessThan 14");
++ check(!n2.lessThan(p2), "lessThan 15");
++ check(!n2.lessThan(n1), "lessThan 16");
++
++ // lessThanOrEqual positive tests
++ check(p1.lessThanOrEqual(p1), "lessThanOrEqual 1");
++ check(p2.lessThanOrEqual(p2), "lessThanOrEqual 2");
++ check(n1.lessThanOrEqual(n1), "lessThanOrEqual 3");
++ check(n2.lessThanOrEqual(n2), "lessThanOrEqual 4");
++
++ check(p1.lessThanOrEqual(p2), "lessThanOrEqual 5");
++ check(p1.lessThanOrEqual(n1), "lessThanOrEqual 6");
++ check(p1.lessThanOrEqual(n2), "lessThanOrEqual 7");
++ check(p2.lessThanOrEqual(n1), "lessThanOrEqual 8");
++ check(p2.lessThanOrEqual(n2), "lessThanOrEqual 9");
++ check(n1.lessThanOrEqual(n2), "lessThanOrEqual 10");
++
++ // lessThanOrEqual negative tests
++ check(!p2.lessThanOrEqual(p1), "lessThanOrEqual 11");
++ check(!n1.lessThanOrEqual(p1), "lessThanOrEqual 12");
++ check(!n2.lessThanOrEqual(p1), "lessThanOrEqual 13");
++ check(!n1.lessThanOrEqual(p2), "lessThanOrEqual 14");
++ check(!n2.lessThanOrEqual(p2), "lessThanOrEqual 15");
++ check(!n2.lessThanOrEqual(n1), "lessThanOrEqual 16");
++
++ // greaterThan positive tests
++ check(n2.greaterThan(p1), "greaterThan 1");
++ check(n2.greaterThan(p2), "greaterThan 2");
++ check(n2.greaterThan(n1), "greaterThan 3");
++ check(n1.greaterThan(p1), "greaterThan 4");
++ check(n1.greaterThan(p2), "greaterThan 5");
++ check(p2.greaterThan(p1), "greaterThan 6");
++
++ // greaterThan negative tests
++ check(!p1.greaterThan(p1), "greaterThan 7");
++ check(!p2.greaterThan(p2), "greaterThan 8");
++ check(!n1.greaterThan(n1), "greaterThan 9");
++ check(!n2.greaterThan(n2), "greaterThan 10");
++
++ check(!p1.greaterThan(n2), "greaterThan 11");
++ check(!p2.greaterThan(n2), "greaterThan 12");
++ check(!n1.greaterThan(n2), "greaterThan 13");
++ check(!p1.greaterThan(n1), "greaterThan 14");
++ check(!p2.greaterThan(n1), "greaterThan 15");
++ check(!p1.greaterThan(p2), "greaterThan 16");
++
++ // greaterThanOrEqual positive tests
++ check(p1.greaterThanOrEqual(p1), "greaterThanOrEqual 1");
++ check(p2.greaterThanOrEqual(p2), "greaterThanOrEqual 2");
++ check(n1.greaterThanOrEqual(n1), "greaterThanOrEqual 3");
++ check(n2.greaterThanOrEqual(n2), "greaterThanOrEqual 4");
++
++ check(n2.greaterThanOrEqual(p1), "greaterThanOrEqual 5");
++ check(n2.greaterThanOrEqual(p2), "greaterThanOrEqual 6");
++ check(n2.greaterThanOrEqual(n1), "greaterThanOrEqual 7");
++ check(n1.greaterThanOrEqual(p1), "greaterThanOrEqual 8");
++ check(n1.greaterThanOrEqual(p2), "greaterThanOrEqual 9");
++ check(p2.greaterThanOrEqual(p1), "greaterThanOrEqual 10");
++
++ // greaterThanOrEqual negative tests
++ check(!p1.greaterThanOrEqual(n2), "greaterThanOrEqual 11");
++ check(!p2.greaterThanOrEqual(n2), "greaterThanOrEqual 12");
++ check(!n1.greaterThanOrEqual(n2), "greaterThanOrEqual 13");
++ check(!p1.greaterThanOrEqual(n1), "greaterThanOrEqual 14");
++ check(!p2.greaterThanOrEqual(n1), "greaterThanOrEqual 15");
++ check(!p1.greaterThanOrEqual(p2), "greaterThanOrEqual 16");
++
++ System.err.println("BsdAddress: all tests passed successfully.");
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import java.io.*;
++import java.util.*;
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++import sun.jvm.hotspot.debugger.x86.*;
++import sun.jvm.hotspot.debugger.amd64.*;
++import sun.jvm.hotspot.debugger.bsd.x86.*;
++import sun.jvm.hotspot.debugger.bsd.amd64.*;
++import sun.jvm.hotspot.utilities.*;
++
++class BsdCDebugger implements CDebugger {
++ private BsdDebugger dbg;
++
++ BsdCDebugger(BsdDebugger dbg) {
++ this.dbg = dbg;
++ }
++
++ public List getThreadList() throws DebuggerException {
++ return dbg.getThreadList();
++ }
++
++ public List/*<LoadObject>*/ getLoadObjectList() throws DebuggerException {
++ return dbg.getLoadObjectList();
++ }
++
++ public LoadObject loadObjectContainingPC(Address pc) throws DebuggerException {
++ if (pc == null) {
++ return null;
++ }
++ List objs = getLoadObjectList();
++ Object[] arr = objs.toArray();
++ // load objects are sorted by base address, do binary search
++ int mid = -1;
++ int low = 0;
++ int high = arr.length - 1;
++
++ while (low <= high) {
++ mid = (low + high) >> 1;
++ LoadObject midVal = (LoadObject) arr[mid];
++ long cmp = pc.minus(midVal.getBase());
++ if (cmp < 0) {
++ high = mid - 1;
++ } else if (cmp > 0) {
++ long size = midVal.getSize();
++ if (cmp >= size) {
++ low = mid + 1;
++ } else {
++ return (LoadObject) arr[mid];
++ }
++ } else { // match found
++ return (LoadObject) arr[mid];
++ }
++ }
++ // no match found.
++ return null;
++ }
++
++ public CFrame topFrameForThread(ThreadProxy thread) throws DebuggerException {
++ String cpu = dbg.getCPU();
++ if (cpu.equals("x86")) {
++ X86ThreadContext context = (X86ThreadContext) thread.getContext();
++ Address ebp = context.getRegisterAsAddress(X86ThreadContext.EBP);
++ if (ebp == null) return null;
++ Address pc = context.getRegisterAsAddress(X86ThreadContext.EIP);
++ if (pc == null) return null;
++ return new BsdX86CFrame(dbg, ebp, pc);
++ } else if (cpu.equals("amd64")) {
++ AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext();
++ Address rbp = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
++ if (rbp == null) return null;
++ Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP);
++ if (pc == null) return null;
++ return new BsdAMD64CFrame(dbg, rbp, pc);
++ } else {
++ throw new DebuggerException(cpu + " is not yet supported");
++ }
++ }
++
++ public String getNameOfFile(String fileName) {
++ return new File(fileName).getName();
++ }
++
++ public ProcessControl getProcessControl() throws DebuggerException {
++ // FIXME: after stabs parser
++ return null;
++ }
++
++ public boolean canDemangle() {
++ return false;
++ }
++
++ public String demangle(String sym) {
++ throw new UnsupportedOperationException();
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,82 @@
++/*
++ * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import java.util.List;
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++
++/** An extension of the JVMDebugger interface with a few additions to
++ support 32-bit vs. 64-bit debugging as well as features required
++ by the architecture-specific subpackages. */
++
++public interface BsdDebugger extends JVMDebugger {
++ public String addressValueToString(long address) throws DebuggerException;
++ public boolean readJBoolean(long address) throws DebuggerException;
++ public byte readJByte(long address) throws DebuggerException;
++ public char readJChar(long address) throws DebuggerException;
++ public double readJDouble(long address) throws DebuggerException;
++ public float readJFloat(long address) throws DebuggerException;
++ public int readJInt(long address) throws DebuggerException;
++ public long readJLong(long address) throws DebuggerException;
++ public short readJShort(long address) throws DebuggerException;
++ public long readCInteger(long address, long numBytes, boolean isUnsigned)
++ throws DebuggerException;
++ public BsdAddress readAddress(long address) throws DebuggerException;
++ public BsdAddress readCompOopAddress(long address) throws DebuggerException;
++ public BsdOopHandle readOopHandle(long address) throws DebuggerException;
++ public BsdOopHandle readCompOopHandle(long address) throws DebuggerException;
++ public long[] getThreadIntegerRegisterSet(int lwp_id) throws DebuggerException;
++ public long getAddressValue(Address addr) throws DebuggerException;
++ public Address newAddress(long value) throws DebuggerException;
++
++ // For BsdCDebugger
++ public List getThreadList();
++ public List getLoadObjectList();
++ public ClosestSymbol lookup(long address);
++
++ // NOTE: this interface implicitly contains the following methods:
++ // From the Debugger interface via JVMDebugger
++ // public void attach(int processID) throws DebuggerException;
++ // public void attach(String executableName, String coreFileName) throws DebuggerException;
++ // public boolean detach();
++ // public Address parseAddress(String addressString) throws NumberFormatException;
++ // public String getOS();
++ // public String getCPU();
++ // From the SymbolLookup interface via Debugger and JVMDebugger
++ // public Address lookup(String objectName, String symbol);
++ // public OopHandle lookupOop(String objectName, String symbol);
++ // From the JVMDebugger interface
++ // public void configureJavaPrimitiveTypeSizes(long jbooleanSize,
++ // long jbyteSize,
++ // long jcharSize,
++ // long jdoubleSize,
++ // long jfloatSize,
++ // long jintSize,
++ // long jlongSize,
++ // long jshortSize);
++ // From the ThreadAccess interface via Debugger and JVMDebugger
++ // public ThreadProxy getThreadForIdentifierAddress(Address addr);
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,595 @@
++/*
++ * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import java.io.*;
++import java.net.*;
++import java.util.*;
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.x86.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++import sun.jvm.hotspot.utilities.*;
++import java.lang.reflect.*;
++
++/** <P> An implementation of the JVMDebugger interface. The basic debug
++ facilities are implemented through ptrace interface in the JNI code
++ (libsaproc.so). Library maps and symbol table management are done in
++ JNI. </P>
++
++ <P> <B>NOTE</B> that since we have the notion of fetching "Java
++ primitive types" from the remote process (which might have
++ different sizes than we expect) we have a bootstrapping
++ problem. We need to know the sizes of these types before we can
++ fetch them. The current implementation solves this problem by
++ requiring that it be configured with these type sizes before they
++ can be fetched. The readJ(Type) routines here will throw a
++ RuntimeException if they are called before the debugger is
++ configured with the Java primitive type sizes. </P> */
++
++public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
++ private boolean useGCC32ABI;
++ private boolean attached;
++ private long p_ps_prochandle; // native debugger handle
++ private boolean isCore;
++
++ // CDebugger support
++ private BsdCDebugger cdbg;
++
++ // threadList and loadObjectList are filled by attach0 method
++ private List threadList;
++ private List loadObjectList;
++
++ // called by native method lookupByAddress0
++ private ClosestSymbol createClosestSymbol(String name, long offset) {
++ return new ClosestSymbol(name, offset);
++ }
++
++ // called by native method attach0
++ private LoadObject createLoadObject(String fileName, long textsize,
++ long base) {
++ File f = new File(fileName);
++ Address baseAddr = newAddress(base);
++ return new SharedObject(this, fileName, f.length(), baseAddr);
++ }
++
++ // native methods
++
++ private native static void init0()
++ throws DebuggerException;
++ private native void attach0(int pid)
++ throws DebuggerException;
++ private native void attach0(String execName, String coreName)
++ throws DebuggerException;
++ private native void detach0()
++ throws DebuggerException;
++ private native long lookupByName0(String objectName, String symbol)
++ throws DebuggerException;
++ private native ClosestSymbol lookupByAddress0(long address)
++ throws DebuggerException;
++ private native long[] getThreadIntegerRegisterSet0(int lwp_id)
++ throws DebuggerException;
++ private native byte[] readBytesFromProcess0(long address, long numBytes)
++ throws DebuggerException;
++ public native static int getAddressSize() ;
++
++ // Note on Bsd threads are really processes. When target process is
++ // attached by a serviceability agent thread, only that thread can do
++ // ptrace operations on the target. This is because from kernel's point
++ // view, other threads are just separate processes and they are not
++ // attached to the target. When they attempt to make ptrace calls,
++ // an ESRCH error will be returned as kernel believes target is not
++ // being traced by the caller.
++ // To work around the problem, we use a worker thread here to handle
++ // all JNI functions that are making ptrace calls.
++
++ interface WorkerThreadTask {
++ public void doit(BsdDebuggerLocal debugger) throws DebuggerException;
++ }
++
++ class BsdDebuggerLocalWorkerThread extends Thread {
++ BsdDebuggerLocal debugger;
++ WorkerThreadTask task;
++ DebuggerException lastException;
++
++ public BsdDebuggerLocalWorkerThread(BsdDebuggerLocal debugger) {
++ this.debugger = debugger;
++ setDaemon(true);
++ }
++
++ public void run() {
++ synchronized (workerThread) {
++ for (;;) {
++ if (task != null) {
++ lastException = null;
++ try {
++ task.doit(debugger);
++ } catch (DebuggerException exp) {
++ lastException = exp;
++ }
++ task = null;
++ workerThread.notifyAll();
++ }
++
++ try {
++ workerThread.wait();
++ } catch (InterruptedException x) {}
++ }
++ }
++ }
++
++ public WorkerThreadTask execute(WorkerThreadTask task) throws DebuggerException {
++ synchronized (workerThread) {
++ this.task = task;
++ workerThread.notifyAll();
++ while (this.task != null) {
++ try {
++ workerThread.wait();
++ } catch (InterruptedException x) {}
++ }
++ if (lastException != null) {
++ throw new DebuggerException(lastException);
++ } else {
++ return task;
++ }
++ }
++ }
++ }
++
++ private BsdDebuggerLocalWorkerThread workerThread = null;
++
++ //----------------------------------------------------------------------
++ // Implementation of Debugger interface
++ //
++
++ /** <P> machDesc may not be null. </P>
++
++ <P> useCache should be set to true if debugging is being done
++ locally, and to false if the debugger is being created for the
++ purpose of supporting remote debugging. </P> */
++ public BsdDebuggerLocal(MachineDescription machDesc,
++ boolean useCache) throws DebuggerException {
++ this.machDesc = machDesc;
++ utils = new DebuggerUtilities(machDesc.getAddressSize(),
++ machDesc.isBigEndian()) {
++ public void checkAlignment(long address, long alignment) {
++ // Need to override default checkAlignment because we need to
++ // relax alignment constraints on Bsd/x86
++ if ( (address % alignment != 0)
++ &&(alignment != 8 || address % 4 != 0)) {
++ throw new UnalignedAddressException(
++ "Trying to read at address: "
++ + addressValueToString(address)
++ + " with alignment: " + alignment,
++ address);
++ }
++ }
++ };
++
++ if (useCache) {
++ // FIXME: re-test necessity of cache on Bsd, where data
++ // fetching is faster
++ // Cache portion of the remote process's address space.
++ // Fetching data over the socket connection to dbx is slow.
++ // Might be faster if we were using a binary protocol to talk to
++ // dbx, but would have to test. For now, this cache works best
++ // if it covers the entire heap of the remote process. FIXME: at
++ // least should make this tunable from the outside, i.e., via
++ // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
++ // size must be adjusted to be the hardware's page size.
++ // (FIXME: should pick this up from the debugger.)
++ if (getCPU().equals("ia64")) {
++ initCache(16384, parseCacheNumPagesProperty(1024));
++ } else {
++ initCache(4096, parseCacheNumPagesProperty(4096));
++ }
++ }
++
++ workerThread = new BsdDebuggerLocalWorkerThread(this);
++ workerThread.start();
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public boolean hasProcessList() throws DebuggerException {
++ return false;
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public List getProcessList() throws DebuggerException {
++ throw new DebuggerException("getProcessList not implemented yet");
++ }
++
++ private void checkAttached() throws DebuggerException {
++ if (attached) {
++ if (isCore) {
++ throw new DebuggerException("attached to a core dump already");
++ } else {
++ throw new DebuggerException("attached to a process already");
++ }
++ }
++ }
++
++ private void requireAttach() {
++ if (! attached) {
++ throw new RuntimeException("not attached to a process or a core!");
++ }
++ }
++
++ /* called from attach methods */
++ private void findABIVersion() throws DebuggerException {
++ if (lookupByName0("libjvm.so", "__vt_10JavaThread") != 0 ||
++ lookupByName0("libjvm_g.so", "__vt_10JavaThread") != 0) {
++ // old C++ ABI
++ useGCC32ABI = false;
++ } else {
++ // new C++ ABI
++ useGCC32ABI = true;
++ }
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public synchronized void attach(int processID) throws DebuggerException {
++ checkAttached();
++ threadList = new ArrayList();
++ loadObjectList = new ArrayList();
++ class AttachTask implements WorkerThreadTask {
++ int pid;
++ public void doit(BsdDebuggerLocal debugger) {
++ debugger.attach0(pid);
++ debugger.attached = true;
++ debugger.isCore = false;
++ findABIVersion();
++ }
++ }
++
++ AttachTask task = new AttachTask();
++ task.pid = processID;
++ workerThread.execute(task);
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public synchronized void attach(String execName, String coreName) {
++ checkAttached();
++ threadList = new ArrayList();
++ loadObjectList = new ArrayList();
++ attach0(execName, coreName);
++ attached = true;
++ isCore = true;
++ findABIVersion();
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public synchronized boolean detach() {
++ if (!attached) {
++ return false;
++ }
++
++ threadList = null;
++ loadObjectList = null;
++
++ if (isCore) {
++ detach0();
++ attached = false;
++ return true;
++ } else {
++ class DetachTask implements WorkerThreadTask {
++ boolean result = false;
++
++ public void doit(BsdDebuggerLocal debugger) {
++ debugger.detach0();
++ debugger.attached = false;
++ result = true;
++ }
++ }
++
++ DetachTask task = new DetachTask();
++ workerThread.execute(task);
++ return task.result;
++ }
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public Address parseAddress(String addressString)
++ throws NumberFormatException {
++ long addr = utils.scanAddress(addressString);
++ if (addr == 0) {
++ return null;
++ }
++ return new BsdAddress(this, addr);
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public String getOS() {
++ return PlatformInfo.getOS();
++ }
++
++ /** From the Debugger interface via JVMDebugger */
++ public String getCPU() {
++ return PlatformInfo.getCPU();
++ }
++
++ public boolean hasConsole() throws DebuggerException {
++ return false;
++ }
++
++ public String consoleExecuteCommand(String cmd) throws DebuggerException {
++ throw new DebuggerException("No debugger console available on Bsd");
++ }
++
++ public String getConsolePrompt() throws DebuggerException {
++ return null;
++ }
++
++ /* called from lookup */
++ private long handleGCC32ABI(long addr, String symbol) throws DebuggerException {
++ if (useGCC32ABI && symbol.startsWith("_ZTV")) {
++ return addr + (2 * machDesc.getAddressSize());
++ } else {
++ return addr;
++ }
++ }
++
++ /** From the SymbolLookup interface via Debugger and JVMDebugger */
++ public synchronized Address lookup(String objectName, String symbol) {
++ requireAttach();
++ if (!attached) {
++ return null;
++ }
++
++ if (isCore) {
++ long addr = lookupByName0(objectName, symbol);
++ return (addr == 0)? null : new BsdAddress(this, handleGCC32ABI(addr, symbol));
++ } else {
++ class LookupByNameTask implements WorkerThreadTask {
++ String objectName, symbol;
++ Address result;
++
++ public void doit(BsdDebuggerLocal debugger) {
++ long addr = debugger.lookupByName0(objectName, symbol);
++ result = (addr == 0 ? null : new BsdAddress(debugger, handleGCC32ABI(addr, symbol)));
++ }
++ }
++
++ LookupByNameTask task = new LookupByNameTask();
++ task.objectName = objectName;
++ task.symbol = symbol;
++ workerThread.execute(task);
++ return task.result;
++ }
++ }
++
++ /** From the SymbolLookup interface via Debugger and JVMDebugger */
++ public synchronized OopHandle lookupOop(String objectName, String symbol) {
++ Address addr = lookup(objectName, symbol);
++ if (addr == null) {
++ return null;
++ }
++ return addr.addOffsetToAsOopHandle(0);
++ }
++
++ /** From the Debugger interface */
++ public MachineDescription getMachineDescription() {
++ return machDesc;
++ }
++
++ //----------------------------------------------------------------------
++ // Implementation of ThreadAccess interface
++ //
++
++ /** From the ThreadAccess interface via Debugger and JVMDebugger */
++ public ThreadProxy getThreadForIdentifierAddress(Address addr) {
++ return new BsdThread(this, addr);
++ }
++
++ /** From the ThreadAccess interface via Debugger and JVMDebugger */
++ public ThreadProxy getThreadForThreadId(long id) {
++ return new BsdThread(this, id);
++ }
++
++ //----------------------------------------------------------------------
++ // Internal routines (for implementation of BsdAddress).
++ // These must not be called until the MachineDescription has been set up.
++ //
++
++ /** From the BsdDebugger interface */
++ public String addressValueToString(long address) {
++ return utils.addressValueToString(address);
++ }
++
++ /** From the BsdDebugger interface */
++ public BsdAddress readAddress(long address)
++ throws UnmappedAddressException, UnalignedAddressException {
++ long value = readAddressValue(address);
++ return (value == 0 ? null : new BsdAddress(this, value));
++ }
++ public BsdAddress readCompOopAddress(long address)
++ throws UnmappedAddressException, UnalignedAddressException {
++ long value = readCompOopAddressValue(address);
++ return (value == 0 ? null : new BsdAddress(this, value));
++ }
++
++ /** From the BsdDebugger interface */
++ public BsdOopHandle readOopHandle(long address)
++ throws UnmappedAddressException, UnalignedAddressException,
++ NotInHeapException {
++ long value = readAddressValue(address);
++ return (value == 0 ? null : new BsdOopHandle(this, value));
++ }
++ public BsdOopHandle readCompOopHandle(long address)
++ throws UnmappedAddressException, UnalignedAddressException,
++ NotInHeapException {
++ long value = readCompOopAddressValue(address);
++ return (value == 0 ? null : new BsdOopHandle(this, value));
++ }
++
++ //----------------------------------------------------------------------
++ // Thread context access
++ //
++
++ public synchronized long[] getThreadIntegerRegisterSet(int lwp_id)
++ throws DebuggerException {
++ requireAttach();
++ if (isCore) {
++ return getThreadIntegerRegisterSet0(lwp_id);
++ } else {
++ class GetThreadIntegerRegisterSetTask implements WorkerThreadTask {
++ int lwp_id;
++ long[] result;
++ public void doit(BsdDebuggerLocal debugger) {
++ result = debugger.getThreadIntegerRegisterSet0(lwp_id);
++ }
++ }
++
++ GetThreadIntegerRegisterSetTask task = new GetThreadIntegerRegisterSetTask();
++ task.lwp_id = lwp_id;
++ workerThread.execute(task);
++ return task.result;
++ }
++ }
++
++ /** Need to override this to relax alignment checks on x86. */
++ public long readCInteger(long address, long numBytes, boolean isUnsigned)
++ throws UnmappedAddressException, UnalignedAddressException {
++ // Only slightly relaxed semantics -- this is a hack, but is
++ // necessary on x86 where it seems the compiler is
++ // putting some global 64-bit data on 32-bit boundaries
++ if (numBytes == 8) {
++ utils.checkAlignment(address, 4);
++ } else {
++ utils.checkAlignment(address, numBytes);
++ }
++ byte[] data = readBytes(address, numBytes);
++ return utils.dataToCInteger(data, isUnsigned);
++ }
++
++ // Overridden from DebuggerBase because we need to relax alignment
++ // constraints on x86
++ public long readJLong(long address)
++ throws UnmappedAddressException, UnalignedAddressException {
++ utils.checkAlignment(address, jintSize);
++ byte[] data = readBytes(address, jlongSize);
++ return utils.dataToJLong(data, jlongSize);
++ }
++
++ //----------------------------------------------------------------------
++ // Address access. Can not be package private, but should only be
++ // accessed by the architecture-specific subpackages.
++
++ /** From the BsdDebugger interface */
++ public long getAddressValue(Address addr) {
++ if (addr == null) return 0;
++ return ((BsdAddress) addr).getValue();
++ }
++
++ /** From the BsdDebugger interface */
++ public Address newAddress(long value) {
++ if (value == 0) return null;
++ return new BsdAddress(this, value);
++ }
++
++ /** From the BsdCDebugger interface */
++ public List/*<ThreadProxy>*/ getThreadList() {
++ requireAttach();
++ return threadList;
++ }
++
++ /** From the BsdCDebugger interface */
++ public List/*<LoadObject>*/ getLoadObjectList() {
++ requireAttach();
++ return loadObjectList;
++ }
++
++ /** From the BsdCDebugger interface */
++ public synchronized ClosestSymbol lookup(long addr) {
++ requireAttach();
++ if (isCore) {
++ return lookupByAddress0(addr);
++ } else {
++ class LookupByAddressTask implements WorkerThreadTask {
++ long addr;
++ ClosestSymbol result;
++
++ public void doit(BsdDebuggerLocal debugger) {
++ result = debugger.lookupByAddress0(addr);
++ }
++ }
++
++ LookupByAddressTask task = new LookupByAddressTask();
++ task.addr = addr;
++ workerThread.execute(task);
++ return task.result;
++ }
++ }
++
++ public CDebugger getCDebugger() {
++ if (cdbg == null) {
++ String cpu = getCPU();
++ if (cpu.equals("ia64") ) {
++ // IA-64 is not supported because of stack-walking issues
++ return null;
++ }
++ cdbg = new BsdCDebugger(this);
++ }
++ return cdbg;
++ }
++
++ /** This reads bytes from the remote process. */
++ public synchronized ReadResult readBytesFromProcess(long address,
++ long numBytes) throws UnmappedAddressException, DebuggerException {
++ requireAttach();
++ if (isCore) {
++ byte[] res = readBytesFromProcess0(address, numBytes);
++ return (res != null)? new ReadResult(res) : new ReadResult(address);
++ } else {
++ class ReadBytesFromProcessTask implements WorkerThreadTask {
++ long address, numBytes;
++ ReadResult result;
++ public void doit(BsdDebuggerLocal debugger) {
++ byte[] res = debugger.readBytesFromProcess0(address, numBytes);
++ if (res != null)
++ result = new ReadResult(res);
++ else
++ result = new ReadResult(address);
++ }
++ }
++
++ ReadBytesFromProcessTask task = new ReadBytesFromProcessTask();
++ task.address = address;
++ task.numBytes = numBytes;
++ workerThread.execute(task);
++ return task.result;
++ }
++ }
++
++ public void writeBytesToProcess(long address, long numBytes, byte[] data)
++ throws UnmappedAddressException, DebuggerException {
++ // FIXME
++ throw new DebuggerException("Unimplemented");
++ }
++
++ static {
++ System.loadLibrary("saproc");
++ init0();
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdOopHandle.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdOopHandle.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdOopHandle.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdOopHandle.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import sun.jvm.hotspot.debugger.*;
++
++class BsdOopHandle extends BsdAddress implements OopHandle {
++ BsdOopHandle(BsdDebugger debugger, long addr) {
++ super(debugger, addr);
++ }
++
++ public boolean equals(Object arg) {
++ if (arg == null) {
++ return false;
++ }
++
++ if (!(arg instanceof BsdOopHandle)) {
++ return false;
++ }
++
++ return (addr == ((BsdAddress) arg).addr);
++ }
++
++ public Address addOffsetTo (long offset) throws UnsupportedOperationException {
++ throw new UnsupportedOperationException("addOffsetTo not applicable to OopHandles (interior object pointers not allowed)");
++ }
++
++ public Address andWithMask(long mask) throws UnsupportedOperationException {
++ throw new UnsupportedOperationException("andWithMask not applicable to OopHandles (i.e., anything but C addresses)");
++ }
++
++ public Address orWithMask(long mask) throws UnsupportedOperationException {
++ throw new UnsupportedOperationException("orWithMask not applicable to OopHandles (i.e., anything but C addresses)");
++ }
++
++ public Address xorWithMask(long mask) throws UnsupportedOperationException {
++ throw new UnsupportedOperationException("xorWithMask not applicable to OopHandles (i.e., anything but C addresses)");
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.bsd.amd64.*;
++import sun.jvm.hotspot.debugger.bsd.x86.*;
++
++class BsdThreadContextFactory {
++ static ThreadContext createThreadContext(BsdDebugger dbg) {
++ String cpu = dbg.getCPU();
++ if (cpu.equals("x86")) {
++ return new BsdX86ThreadContext(dbg);
++ } else if (cpu.equals("amd64")) {
++ return new BsdAMD64ThreadContext(dbg);
++ } else {
++ throw new RuntimeException("cpu " + cpu + " is not yet supported");
++ }
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import sun.jvm.hotspot.debugger.*;
++
++class BsdThread implements ThreadProxy {
++ private BsdDebugger debugger;
++ private int lwp_id;
++
++ /** The address argument must be the address of the _thread_id in the
++ OSThread. It's value is result ::gettid() call. */
++ BsdThread(BsdDebugger debugger, Address addr) {
++ this.debugger = debugger;
++ // FIXME: size of data fetched here should be configurable.
++ // However, making it so would produce a dependency on the "types"
++ // package from the debugger package, which is not desired.
++ this.lwp_id = (int) addr.getCIntegerAt(0, 4, true);
++ }
++
++ BsdThread(BsdDebugger debugger, long id) {
++ this.debugger = debugger;
++ this.lwp_id = (int) id;
++ }
++
++ public boolean equals(Object obj) {
++ if ((obj == null) || !(obj instanceof BsdThread)) {
++ return false;
++ }
++
++ return (((BsdThread) obj).lwp_id == lwp_id);
++ }
++
++ public int hashCode() {
++ return lwp_id;
++ }
++
++ public String toString() {
++ return Integer.toString(lwp_id);
++ }
++
++ public ThreadContext getContext() throws IllegalThreadStateException {
++ long[] data = debugger.getThreadIntegerRegisterSet(lwp_id);
++ ThreadContext context = BsdThreadContextFactory.createThreadContext(debugger);
++ for (int i = 0; i < data.length; i++) {
++ context.setRegister(i, data[i]);
++ }
++ return context;
++ }
++
++ public boolean canSetContext() throws DebuggerException {
++ return false;
++ }
++
++ public void setContext(ThreadContext context)
++ throws IllegalThreadStateException, DebuggerException {
++ throw new DebuggerException("Unimplemented");
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/SharedObject.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/SharedObject.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/SharedObject.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/SharedObject.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++import sun.jvm.hotspot.debugger.posix.*;
++
++/** A Object can represent either a .so or an a.out file. */
++
++class SharedObject extends DSO {
++ SharedObject(BsdDebugger dbg, String filename, long size, Address relocation) {
++ super(filename, size, relocation);
++ this.dbg = dbg;
++ }
++
++ protected Address newAddress(long address) {
++ return dbg.newAddress(address);
++ }
++
++ protected long getAddressValue(Address addr) {
++ return dbg.getAddressValue(addr);
++ }
++
++ private BsdDebugger dbg;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86CFrame.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86CFrame.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86CFrame.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86CFrame.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd.x86;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.bsd.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++import sun.jvm.hotspot.debugger.cdbg.basic.*;
++
++final public class BsdX86CFrame extends BasicCFrame {
++ // package/class internals only
++ public BsdX86CFrame(BsdDebugger dbg, Address ebp, Address pc) {
++ super(dbg.getCDebugger());
++ this.ebp = ebp;
++ this.pc = pc;
++ this.dbg = dbg;
++ }
++
++ // override base class impl to avoid ELF parsing
++ public ClosestSymbol closestSymbolToPC() {
++ // try native lookup in debugger.
++ return dbg.lookup(dbg.getAddressValue(pc()));
++ }
++
++ public Address pc() {
++ return pc;
++ }
++
++ public Address localVariableBase() {
++ return ebp;
++ }
++
++ public CFrame sender() {
++ if (ebp == null) {
++ return null;
++ }
++
++ Address nextEBP = ebp.getAddressAt( 0 * ADDRESS_SIZE);
++ if (nextEBP == null) {
++ return null;
++ }
++ Address nextPC = ebp.getAddressAt( 1 * ADDRESS_SIZE);
++ if (nextPC == null) {
++ return null;
++ }
++ return new BsdX86CFrame(dbg, nextEBP, nextPC);
++ }
++
++ private static final int ADDRESS_SIZE = 4;
++ private Address pc;
++ private Address ebp;
++ private BsdDebugger dbg;
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86ThreadContext.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86ThreadContext.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86ThreadContext.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/x86/BsdX86ThreadContext.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.bsd.x86;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.x86.*;
++import sun.jvm.hotspot.debugger.bsd.*;
++
++public class BsdX86ThreadContext extends X86ThreadContext {
++ private BsdDebugger debugger;
++
++ public BsdX86ThreadContext(BsdDebugger debugger) {
++ super();
++ this.debugger = debugger;
++ }
++
++ public void setRegisterAsAddress(int index, Address value) {
++ setRegister(index, debugger.getAddressValue(value));
++ }
++
++ public Address getRegisterAsAddress(int index) {
++ return debugger.newAddress(getRegister(index));
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java 2013-04-08 01:49:33.582321490 +0100
+@@ -28,6 +28,7 @@
+ import java.net.*;
+ import java.rmi.*;
+ import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.bsd.*;
+ import sun.jvm.hotspot.debugger.proc.*;
+ import sun.jvm.hotspot.debugger.remote.*;
+ import sun.jvm.hotspot.debugger.windbg.*;
+@@ -335,6 +336,8 @@
+ setupDebuggerWin32();
+ } else if (os.equals("linux")) {
+ setupDebuggerLinux();
++ } else if (os.equals("bsd")) {
++ setupDebuggerBsd();
+ } else {
+ // Add support for more operating systems here
+ throw new DebuggerException("Operating system " + os + " not yet supported");
+@@ -390,6 +393,10 @@
+ db = new HotSpotTypeDataBase(machDesc,
+ new LinuxVtblAccess(debugger, jvmLibNames),
+ debugger, jvmLibNames);
++ } else if (os.equals("bsd")) {
++ db = new HotSpotTypeDataBase(machDesc,
++ new BsdVtblAccess(debugger, jvmLibNames),
++ debugger, jvmLibNames);
+ } else {
+ throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess yet)");
+ }
+@@ -477,6 +484,8 @@
+ setupJVMLibNamesWin32();
+ } else if (os.equals("linux")) {
+ setupJVMLibNamesLinux();
++ } else if (os.equals("bsd")) {
++ setupJVMLibNamesBsd();
+ } else {
+ throw new RuntimeException("Unknown OS type");
+ }
+@@ -554,6 +563,31 @@
+ jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" };
+ }
+
++ //
++ // BSD
++ //
++
++ private void setupDebuggerBsd() {
++ setupJVMLibNamesBsd();
++
++ if (cpu.equals("x86")) {
++ machDesc = new MachineDescriptionIntelX86();
++ } else if (cpu.equals("amd64")) {
++ machDesc = new MachineDescriptionAMD64();
++ } else {
++ throw new DebuggerException("BSD only supported on x86/amd64");
++ }
++
++ BsdDebuggerLocal dbg = new BsdDebuggerLocal(machDesc, !isServer);
++ debugger = dbg;
++
++ attachDebugger();
++ }
++
++ private void setupJVMLibNamesBsd() {
++ jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" };
++ }
++
+ /** Convenience routine which should be called by per-platform
+ debugger setup. Should not be called when startupMode is
+ REMOTE_MODE. */
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd/BsdSignals.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd/BsdSignals.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd/BsdSignals.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd/BsdSignals.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.runtime.bsd;
++
++public class BsdSignals {
++ private static String[] signalNames = {
++ "", /* No signal 0 */
++ "SIGHUP", /* hangup */
++ "SIGINT", /* interrupt */
++ "SIGQUIT", /* quit */
++ "SIGILL", /* illegal instr. (not reset when caught) */
++ "SIGTRAP", /* trace trap (not reset when caught) */
++ "SIGABRT", /* abort() */
++ "SIGEMT", /* EMT instruction */
++ "SIGFPE", /* floating point exception */
++ "SIGKILL", /* kill (cannot be caught or ignored) */
++ "SIGBUS", /* bus error */
++ "SIGSEGV", /* segmentation violation */
++ "SIGSYS", /* non-existent system call invoked */
++ "SIGPIPE", /* write on a pipe with no one to read it */
++ "SIGALRM", /* alarm clock */
++ "SIGTERM", /* software termination signal from kill */
++ "SIGURG", /* urgent condition on IO channel */
++ "SIGSTOP", /* sendable stop signal not from tty */
++ "SIGTSTP", /* stop signal from tty */
++ "SIGCONT", /* continue a stopped process */
++ "SIGCHLD", /* to parent on child stop or exit */
++ "SIGTTIN", /* to readers pgrp upon background tty read */
++ "SIGTTOU", /* like TTIN if (tp->t_local&LTOSTOP) */
++ "SIGIO", /* input/output possible signal */
++ "SIGXCPU", /* exceeded CPU time limit */
++ "SIGXFSZ", /* exceeded file size limit */
++ "SIGVTALRM", /* virtual time alarm */
++ "SIGPROF", /* profiling time alarm */
++ "SIGWINCH", /* window size changes */
++ "SIGINFO", /* information request */
++ "SIGUSR1", /* user defined signal 1 */
++ "SIGUSR2" /* user defined signal 2 */
++ };
++
++ public static String getSignalName(int sigNum) {
++ if ((sigNum <= 0) || (sigNum >= signalNames.length)) {
++ // Probably best to fail in a non-destructive way
++ return "<Error: Illegal signal number " + sigNum + ">";
++ }
++ return signalNames[sigNum];
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.runtime.bsd_amd64;
++
++import java.io.*;
++import java.util.*;
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.amd64.*;
++import sun.jvm.hotspot.runtime.*;
++import sun.jvm.hotspot.runtime.amd64.*;
++import sun.jvm.hotspot.runtime.x86.*;
++import sun.jvm.hotspot.types.*;
++import sun.jvm.hotspot.utilities.*;
++
++public class BsdAMD64JavaThreadPDAccess implements JavaThreadPDAccess {
++ private static AddressField lastJavaFPField;
++ private static AddressField osThreadField;
++
++ // Field from OSThread
++ private static CIntegerField osThreadThreadIDField;
++
++ // This is currently unneeded but is being kept in case we change
++ // the currentFrameGuess algorithm
++ private static final long GUESS_SCAN_RANGE = 128 * 1024;
++
++ static {
++ VM.registerVMInitializedObserver(new Observer() {
++ public void update(Observable o, Object data) {
++ initialize(VM.getVM().getTypeDataBase());
++ }
++ });
++ }
++
++ private static synchronized void initialize(TypeDataBase db) {
++ Type type = db.lookupType("JavaThread");
++ osThreadField = type.getAddressField("_osthread");
++
++ Type anchorType = db.lookupType("JavaFrameAnchor");
++ lastJavaFPField = anchorType.getAddressField("_last_Java_fp");
++
++ Type osThreadType = db.lookupType("OSThread");
++ osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id");
++ }
++
++ public Address getLastJavaFP(Address addr) {
++ return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset()));
++ }
++
++ public Address getLastJavaPC(Address addr) {
++ return null;
++ }
++
++ public Address getBaseOfStackPointer(Address addr) {
++ return null;
++ }
++
++ public Frame getLastFramePD(JavaThread thread, Address addr) {
++ Address fp = thread.getLastJavaFP();
++ if (fp == null) {
++ return null; // no information
++ }
++ return new X86Frame(thread.getLastJavaSP(), fp);
++ }
++
++ public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
++ return new X86RegisterMap(thread, updateMap);
++ }
++
++ public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
++ ThreadProxy t = getThreadProxy(addr);
++ AMD64ThreadContext context = (AMD64ThreadContext) t.getContext();
++ AMD64CurrentFrameGuess guesser = new AMD64CurrentFrameGuess(context, thread);
++ if (!guesser.run(GUESS_SCAN_RANGE)) {
++ return null;
++ }
++ if (guesser.getPC() == null) {
++ return new X86Frame(guesser.getSP(), guesser.getFP());
++ } else {
++ return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
++ }
++ }
++
++ public void printThreadIDOn(Address addr, PrintStream tty) {
++ tty.print(getThreadProxy(addr));
++ }
++
++ public void printInfoOn(Address threadAddr, PrintStream tty) {
++ tty.print("Thread id: ");
++ printThreadIDOn(threadAddr, tty);
++// tty.println("\nPostJavaState: " + getPostJavaState(threadAddr));
++ }
++
++ public Address getLastSP(Address addr) {
++ ThreadProxy t = getThreadProxy(addr);
++ AMD64ThreadContext context = (AMD64ThreadContext) t.getContext();
++ return context.getRegisterAsAddress(AMD64ThreadContext.RSP);
++ }
++
++ public ThreadProxy getThreadProxy(Address addr) {
++ // Addr is the address of the JavaThread.
++ // Fetch the OSThread (for now and for simplicity, not making a
++ // separate "OSThread" class in this package)
++ Address osThreadAddr = osThreadField.getValue(addr);
++ // Get the address of the _thread_id from the OSThread
++ Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
++
++ JVMDebugger debugger = VM.getVM().getDebugger();
++ return debugger.getThreadForIdentifierAddress(threadIdAddr);
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdSignals.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdSignals.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdSignals.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdSignals.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.runtime.bsd_x86;
++
++public class BsdSignals {
++ private static String[] signalNames = {
++ "", /* No signal 0 */
++ "SIGHUP", /* hangup */
++ "SIGINT", /* interrupt */
++ "SIGQUIT", /* quit */
++ "SIGILL", /* illegal instr. (not reset when caught) */
++ "SIGTRAP", /* trace trap (not reset when caught) */
++ "SIGABRT", /* abort() */
++ "SIGEMT", /* EMT instruction */
++ "SIGFPE", /* floating point exception */
++ "SIGKILL", /* kill (cannot be caught or ignored) */
++ "SIGBUS", /* bus error */
++ "SIGSEGV", /* segmentation violation */
++ "SIGSYS", /* non-existent system call invoked */
++ "SIGPIPE", /* write on a pipe with no one to read it */
++ "SIGALRM", /* alarm clock */
++ "SIGTERM", /* software termination signal from kill */
++ "SIGURG", /* urgent condition on IO channel */
++ "SIGSTOP", /* sendable stop signal not from tty */
++ "SIGTSTP", /* stop signal from tty */
++ "SIGCONT", /* continue a stopped process */
++ "SIGCHLD", /* to parent on child stop or exit */
++ "SIGTTIN", /* to readers pgrp upon background tty read */
++ "SIGTTOU", /* like TTIN if (tp->t_local&LTOSTOP) */
++ "SIGIO", /* input/output possible signal */
++ "SIGXCPU", /* exceeded CPU time limit */
++ "SIGXFSZ", /* exceeded file size limit */
++ "SIGVTALRM", /* virtual time alarm */
++ "SIGPROF", /* profiling time alarm */
++ "SIGWINCH", /* window size changes */
++ "SIGINFO", /* information request */
++ "SIGUSR1", /* user defined signal 1 */
++ "SIGUSR2" /* user defined signal 2 */
++ };
++
++ public static String getSignalName(int sigNum) {
++ if ((sigNum <= 0) || (sigNum >= signalNames.length)) {
++ // Probably best to fail in a non-destructive way
++ return "<Error: Illegal signal number " + sigNum + ">";
++ }
++ return signalNames[sigNum];
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdX86JavaThreadPDAccess.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdX86JavaThreadPDAccess.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdX86JavaThreadPDAccess.java 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_x86/BsdX86JavaThreadPDAccess.java 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,131 @@
++/*
++ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ *
++ */
++
++package sun.jvm.hotspot.runtime.bsd_x86;
++
++import java.io.*;
++import java.util.*;
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.x86.*;
++import sun.jvm.hotspot.runtime.*;
++import sun.jvm.hotspot.runtime.x86.*;
++import sun.jvm.hotspot.types.*;
++import sun.jvm.hotspot.utilities.*;
++
++public class BsdX86JavaThreadPDAccess implements JavaThreadPDAccess {
++ private static AddressField lastJavaFPField;
++ private static AddressField osThreadField;
++
++ // Field from OSThread
++ private static CIntegerField osThreadThreadIDField;
++
++ // This is currently unneeded but is being kept in case we change
++ // the currentFrameGuess algorithm
++ private static final long GUESS_SCAN_RANGE = 128 * 1024;
++
++ static {
++ VM.registerVMInitializedObserver(new Observer() {
++ public void update(Observable o, Object data) {
++ initialize(VM.getVM().getTypeDataBase());
++ }
++ });
++ }
++
++ private static synchronized void initialize(TypeDataBase db) {
++ Type type = db.lookupType("JavaThread");
++ osThreadField = type.getAddressField("_osthread");
++
++ Type anchorType = db.lookupType("JavaFrameAnchor");
++ lastJavaFPField = anchorType.getAddressField("_last_Java_fp");
++
++ Type osThreadType = db.lookupType("OSThread");
++ osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id");
++ }
++
++ public Address getLastJavaFP(Address addr) {
++ return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset()));
++ }
++
++ public Address getLastJavaPC(Address addr) {
++ return null;
++ }
++
++ public Address getBaseOfStackPointer(Address addr) {
++ return null;
++ }
++
++ public Frame getLastFramePD(JavaThread thread, Address addr) {
++ Address fp = thread.getLastJavaFP();
++ if (fp == null) {
++ return null; // no information
++ }
++ return new X86Frame(thread.getLastJavaSP(), fp);
++ }
++
++ public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
++ return new X86RegisterMap(thread, updateMap);
++ }
++
++ public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
++ ThreadProxy t = getThreadProxy(addr);
++ X86ThreadContext context = (X86ThreadContext) t.getContext();
++ X86CurrentFrameGuess guesser = new X86CurrentFrameGuess(context, thread);
++ if (!guesser.run(GUESS_SCAN_RANGE)) {
++ return null;
++ }
++ if (guesser.getPC() == null) {
++ return new X86Frame(guesser.getSP(), guesser.getFP());
++ } else {
++ return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
++ }
++ }
++
++ public void printThreadIDOn(Address addr, PrintStream tty) {
++ tty.print(getThreadProxy(addr));
++ }
++
++ public void printInfoOn(Address threadAddr, PrintStream tty) {
++ tty.print("Thread id: ");
++ printThreadIDOn(threadAddr, tty);
++// tty.println("\nPostJavaState: " + getPostJavaState(threadAddr));
++ }
++
++ public Address getLastSP(Address addr) {
++ ThreadProxy t = getThreadProxy(addr);
++ X86ThreadContext context = (X86ThreadContext) t.getContext();
++ return context.getRegisterAsAddress(X86ThreadContext.ESP);
++ }
++
++ public ThreadProxy getThreadProxy(Address addr) {
++ // Addr is the address of the JavaThread.
++ // Fetch the OSThread (for now and for simplicity, not making a
++ // separate "OSThread" class in this package)
++ Address osThreadAddr = osThreadField.getValue(addr);
++ // Get the address of the _thread_id from the OSThread
++ Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
++
++ JVMDebugger debugger = VM.getVM().getDebugger();
++ return debugger.getThreadForIdentifierAddress(threadIdAddr);
++ }
++}
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java 2013-04-08 01:49:33.582321490 +0100
+@@ -37,6 +37,8 @@
+ import sun.jvm.hotspot.runtime.linux_ia64.LinuxIA64JavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
++import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
++import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess;
+ import sun.jvm.hotspot.utilities.*;
+
+ public class Threads {
+@@ -90,7 +92,12 @@
+ } else if (cpu.equals("sparc")) {
+ access = new LinuxSPARCJavaThreadPDAccess();
+ }
+-
++ } else if (os.equals("bsd")) {
++ if (cpu.equals("x86")) {
++ access = new BsdX86JavaThreadPDAccess();
++ } else if (cpu.equals("amd64")) {
++ access = new BsdAMD64JavaThreadPDAccess();
++ }
+ }
+
+ if (access == null) {
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java 2013-04-08 01:49:33.582321490 +0100
+@@ -37,6 +37,14 @@
+ return "solaris";
+ } else if (os.equals("Linux")) {
+ return "linux";
++ } else if (os.equals("FreeBSD")) {
++ return "bsd";
++ } else if (os.equals("NetBSD")) {
++ return "bsd";
++ } else if (os.equals("OpenBSD")) {
++ return "bsd";
++ } else if (os.equals("Darwin")) {
++ return "bsd";
+ } else if (os.startsWith("Windows")) {
+ return "win32";
+ } else {
+diff -Nru openjdk.orig/hotspot/make/bsd/adlc_updater openjdk/hotspot/make/bsd/adlc_updater
+--- openjdk.orig/hotspot/make/bsd/adlc_updater 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/adlc_updater 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,20 @@
++#! /bin/sh
++#
++# This file is used by adlc.make to selectively update generated
++# adlc files. Because source and target diretories are relative
++# paths, this file is copied to the target build directory before
++# use.
++#
++# adlc-updater <file> <source-dir> <target-dir>
++#
++fix_lines() {
++ # repair bare #line directives in $1 to refer to $2
++ awk < $1 > $1+ '
++ /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
++ {print}
++ ' F2=$2
++ mv $1+ $1
++}
++fix_lines $2/$1 $3/$1
++[ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
++( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
+diff -Nru openjdk.orig/hotspot/make/bsd/build.sh openjdk/hotspot/make/bsd/build.sh
+--- openjdk.orig/hotspot/make/bsd/build.sh 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/build.sh 2013-04-08 01:49:33.582321490 +0100
+@@ -0,0 +1,95 @@
++#! /bin/sh
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Make sure the variable JAVA_HOME is set before running this script.
++
++set -u
++
++
++if [ $# != 2 ]; then
++ echo "Usage : $0 Build_Options Location"
++ echo "Build Options : debug or optimized or basicdebug or basic or clean"
++ echo "Location : specify any workspace which has gamma sources"
++ exit 1
++fi
++
++# Just in case:
++case ${JAVA_HOME} in
++/*) true;;
++?*) JAVA_HOME=`( cd $JAVA_HOME; pwd )`;;
++esac
++
++case `uname -m` in
++ i386|i486|i586|i686)
++ mach=i386
++ ;;
++ *)
++ echo "Unsupported machine: " `uname -m`
++ exit 1
++ ;;
++esac
++
++if [ "${JAVA_HOME}" = "" -o ! -d "${JAVA_HOME}" -o ! -d ${JAVA_HOME}/jre/lib/${mach} ]; then
++ echo "JAVA_HOME needs to be set to a valid JDK path"
++ echo "ksh : export JAVA_HOME=/net/tetrasparc/export/gobi/JDK1.2_fcs_V/bsd"
++ echo "csh : setenv JAVA_HOME /net/tetrasparc/export/gobi/JDK1.2_fcs_V/bsd"
++ exit 1
++fi
++
++
++LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/`uname -p`:\
++${JAVA_HOME}/jre/lib/`uname -p`/native_threads:${LD_LIBRARY_PATH-.}
++
++# This is necessary as long as we are using the old launcher
++# with the new distribution format:
++CLASSPATH=${JAVA_HOME}/jre/lib/rt.jar:${CLASSPATH-.}
++
++
++for gm in gmake gnumake
++do
++ if [ "${GNUMAKE-}" != "" ]; then break; fi
++ ($gm --version >/dev/null) 2>/dev/null && GNUMAKE=$gm
++done
++: ${GNUMAKE:?'Cannot locate the gnumake program. Stop.'}
++
++
++echo "### ENVIRONMENT SETTINGS:"
++export JAVA_HOME ; echo "JAVA_HOME=$JAVA_HOME"
++export LD_LIBRARY_PATH ; echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
++export CLASSPATH ; echo "CLASSPATH=$CLASSPATH"
++export GNUMAKE ; echo "GNUMAKE=$GNUMAKE"
++echo "###"
++
++Build_Options=$1
++Location=$2
++
++case ${Location} in
++/*) true;;
++?*) Location=`(cd ${Location}; pwd)`;;
++esac
++
++echo \
++${GNUMAKE} -f ${Location}/make/bsd/Makefile $Build_Options GAMMADIR=${Location}
++${GNUMAKE} -f ${Location}/make/bsd/Makefile $Build_Options GAMMADIR=${Location}
+diff -Nru openjdk.orig/hotspot/make/bsd/Makefile openjdk/hotspot/make/bsd/Makefile
+--- openjdk.orig/hotspot/make/bsd/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/Makefile 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,371 @@
++#
++# Copyright (c) 1999, 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 makefile creates a build tree and lights off a build.
++# You can go back into the build tree and perform rebuilds or
++# incremental builds as desired. Be sure to reestablish
++# environment variable settings for LD_LIBRARY_PATH and JAVA_HOME.
++
++# The make process now relies on java and javac. These can be
++# specified either implicitly on the PATH, by setting the
++# (JDK-inherited) ALT_BOOTDIR environment variable to full path to a
++# JDK in which bin/java and bin/javac are present and working (e.g.,
++# /usr/local/java/jdk1.3/solaris), or via the (JDK-inherited)
++# default BOOTDIR path value. Note that one of ALT_BOOTDIR
++# or BOOTDIR has to be set. We do *not* search javac, javah, rmic etc.
++# from the PATH.
++#
++# One can set ALT_BOOTDIR or BOOTDIR to point to a jdk that runs on
++# an architecture that differs from the target architecture, as long
++# as the bootstrap jdk runs under the same flavor of OS as the target
++# (i.e., if the target is linux, point to a jdk that runs on a linux
++# box). In order to use such a bootstrap jdk, set the make variable
++# REMOTE to the desired remote command mechanism, e.g.,
++#
++# make REMOTE="rsh -l me myotherlinuxbox"
++
++# Along with VM, Serviceability Agent (SA) is built for SA/JDI binding.
++# JDI binding on SA produces two binaries:
++# 1. sa-jdi.jar - This is build before building libjvm[_g].so
++# Please refer to ./makefiles/sa.make
++# 2. libsa[_g].so - Native library for SA - This is built after
++# libjsig[_g].so (signal interposition library)
++# Please refer to ./makefiles/vm.make
++# If $(GAMMADIR)/agent dir is not present, SA components are not built.
++
++ifeq ($(GAMMADIR),)
++include ../../make/defs.make
++else
++include $(GAMMADIR)/make/defs.make
++endif
++include $(GAMMADIR)/make/$(OSNAME)/makefiles/rules.make
++
++ifndef CC_INTERP
++ ifndef FORCE_TIERED
++ FORCE_TIERED=1
++ endif
++endif
++
++ifdef LP64
++ ifeq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
++ _JUNK_ := $(shell echo >&2 \
++ $(OSNAME) $(ARCH) "*** ERROR: this platform does not support 64-bit compilers!")
++ @exit 1
++ endif
++endif
++
++# we need to set up LP64 correctly to satisfy sanity checks in adlc
++ifneq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
++ MFLAGS += " LP64=1 "
++endif
++
++# pass USE_SUNCC further, through MFLAGS
++ifdef USE_SUNCC
++ MFLAGS += " USE_SUNCC=1 "
++endif
++
++# The following renders pathnames in generated Makefiles valid on
++# machines other than the machine containing the build tree.
++#
++# For example, let's say my build tree lives on /files12 on
++# exact.east.sun.com. This logic will cause GAMMADIR to begin with
++# /net/exact/files12/...
++#
++# We only do this on SunOS variants, for a couple of reasons:
++# * It is extremely rare that source trees exist on other systems
++# * It has been claimed that the Linux automounter is flakey, so
++# changing GAMMADIR in a way that exercises the automounter could
++# prove to be a source of unreliability in the build process.
++# Obviously, this Makefile is only relevant on SunOS boxes to begin
++# with, but the SunOS conditionalization will make it easier to
++# combine Makefiles in the future (assuming we ever do that).
++
++ifeq ($(OSNAME),solaris)
++
++ # prepend current directory to relative pathnames.
++ NEW_GAMMADIR := \
++ $(shell echo $(GAMMADIR) | \
++ sed -e "s=^\([^/].*\)=$(shell pwd)/\1=" \
++ )
++ unexport NEW_GAMMADIR
++
++ # If NEW_GAMMADIR doesn't already start with "/net/":
++ ifeq ($(strip $(filter /net/%,$(NEW_GAMMADIR))),)
++ # prepend /net/$(HOST)
++ # remove /net/$(HOST) if name already began with /home/
++ # remove /net/$(HOST) if name already began with /java/
++ # remove /net/$(HOST) if name already began with /lab/
++ NEW_GAMMADIR := \
++ $(shell echo $(NEW_GAMMADIR) | \
++ sed -e "s=^\(.*\)=/net/$(HOST)\1=" \
++ -e "s=^/net/$(HOST)/home/=/home/=" \
++ -e "s=^/net/$(HOST)/java/=/java/=" \
++ -e "s=^/net/$(HOST)/lab/=/lab/=" \
++ )
++ # Don't use the new value for GAMMADIR unless a file with the new
++ # name actually exists.
++ ifneq ($(wildcard $(NEW_GAMMADIR)),)
++ GAMMADIR := $(NEW_GAMMADIR)
++ endif
++ endif
++
++endif
++
++# BUILDARCH is set to "zero" for Zero builds. VARIANTARCH
++# is used to give the build directories meaningful names.
++VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH))
++
++# There is a (semi-) regular correspondence between make targets and actions:
++#
++# Target Tree Type Build Dir
++#
++# debug compiler2 <os>_<arch>_compiler2/debug
++# fastdebug compiler2 <os>_<arch>_compiler2/fastdebug
++# jvmg compiler2 <os>_<arch>_compiler2/jvmg
++# optimized compiler2 <os>_<arch>_compiler2/optimized
++# profiled compiler2 <os>_<arch>_compiler2/profiled
++# product compiler2 <os>_<arch>_compiler2/product
++#
++# debug1 compiler1 <os>_<arch>_compiler1/debug
++# fastdebug1 compiler1 <os>_<arch>_compiler1/fastdebug
++# jvmg1 compiler1 <os>_<arch>_compiler1/jvmg
++# optimized1 compiler1 <os>_<arch>_compiler1/optimized
++# profiled1 compiler1 <os>_<arch>_compiler1/profiled
++# product1 compiler1 <os>_<arch>_compiler1/product
++#
++# debugcore core <os>_<arch>_core/debug
++# fastdebugcore core <os>_<arch>_core/fastdebug
++# jvmgcore core <os>_<arch>_core/jvmg
++# optimizedcore core <os>_<arch>_core/optimized
++# profiledcore core <os>_<arch>_core/profiled
++# productcore core <os>_<arch>_core/product
++#
++# debugzero zero <os>_<arch>_zero/debug
++# fastdebugzero zero <os>_<arch>_zero/fastdebug
++# jvmgzero zero <os>_<arch>_zero/jvmg
++# optimizedzero zero <os>_<arch>_zero/optimized
++# profiledzero zero <os>_<arch>_zero/profiled
++# productzero zero <os>_<arch>_zero/product
++#
++# debugshark shark <os>_<arch>_shark/debug
++# fastdebugshark shark <os>_<arch>_shark/fastdebug
++# jvmgshark shark <os>_<arch>_shark/jvmg
++# optimizedshark shark <os>_<arch>_shark/optimized
++# profiledshark shark <os>_<arch>_shark/profiled
++# productshark shark <os>_<arch>_shark/product
++#
++# What you get with each target:
++#
++# debug* - "thin" libjvm_g - debug info linked into the gamma_g launcher
++# fastdebug* - optimized compile, but with asserts enabled
++# jvmg* - "fat" libjvm_g - debug info linked into libjvm_g.so
++# optimized* - optimized compile, no asserts
++# profiled* - gprof
++# product* - the shippable thing: optimized compile, no asserts, -DPRODUCT
++
++# This target list needs to be coordinated with the usage message
++# in the build.sh script:
++TARGETS = debug jvmg fastdebug optimized profiled product
++
++ifeq ($(ZERO_BUILD), true)
++ SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
++else
++ SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
++endif
++SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS))
++SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS))
++SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
++SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
++SUBDIRS_ZERO = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
++SUBDIRS_SHARK = $(addprefix $(OSNAME)_$(VARIANTARCH)_shark/,$(TARGETS))
++
++TARGETS_C2 = $(TARGETS)
++TARGETS_C1 = $(addsuffix 1,$(TARGETS))
++TARGETS_TIERED = $(addsuffix tiered,$(TARGETS))
++TARGETS_CORE = $(addsuffix core,$(TARGETS))
++TARGETS_ZERO = $(addsuffix zero,$(TARGETS))
++TARGETS_SHARK = $(addsuffix shark,$(TARGETS))
++
++BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
++BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
++BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) HOTSPOT_BUILD_VERSION=$(HOTSPOT_BUILD_VERSION) JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
++
++BUILDTREE = $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_VARS)
++
++#-------------------------------------------------------------------------------
++
++# Could make everything by default, but that would take a while.
++all:
++ @echo "Try '$(MAKE) <target> ...' where <target> is one or more of"
++ @echo " $(TARGETS_C2)"
++ @echo " $(TARGETS_C1)"
++ @echo " $(TARGETS_CORE)"
++ @echo " $(TARGETS_ZERO)"
++ @echo " $(TARGETS_SHARK)"
++
++checks: check_os_version check_j2se_version
++
++# We do not want people accidentally building on old systems (e.g. Linux 2.2.x,
++# Solaris 2.5.1, 2.6).
++# Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok.
++
++#SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7%
++DISABLE_HOTSPOT_OS_VERSION_CHECK = ok
++OS_VERSION := $(shell uname -r)
++EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION))
++
++check_os_version:
++ifeq ($(DISABLE_HOTSPOT_OS_VERSION_CHECK)$(EMPTY_IF_NOT_SUPPORTED),)
++ $(QUIETLY) >&2 echo "*** This OS is not supported:" `uname -a`; exit 1;
++endif
++
++# jvmti.make requires XSLT (J2SE 1.4.x or newer):
++XSLT_CHECK = $(REMOTE) $(RUN.JAVAP) javax.xml.transform.TransformerFactory
++# If not found then fail fast.
++check_j2se_version:
++ $(QUIETLY) $(XSLT_CHECK) > /dev/null 2>&1; \
++ if [ $$? -ne 0 ]; then \
++ $(REMOTE) $(RUN.JAVA) -version; \
++ echo "*** An XSLT processor (J2SE 1.4.x or newer) is required" \
++ "to bootstrap this build" 1>&2; \
++ exit 1; \
++ fi
++
++$(SUBDIRS_TIERED): $(BUILDTREE_MAKE)
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=tiered
++
++$(SUBDIRS_C2): $(BUILDTREE_MAKE)
++ifeq ($(FORCE_TIERED),1)
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
++else
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=compiler2
++endif
++
++$(SUBDIRS_C1): $(BUILDTREE_MAKE)
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=compiler1
++
++$(SUBDIRS_CORE): $(BUILDTREE_MAKE)
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=core
++
++$(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
++
++$(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero
++ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
++ $(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
++
++platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
++ $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
++
++# Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME
++
++$(TARGETS_C2): $(SUBDIRS_C2)
++ cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS)
++ cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma
++ifdef INSTALL
++ cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install
++endif
++
++$(TARGETS_TIERED): $(SUBDIRS_TIERED)
++ cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS)
++ cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma
++ifdef INSTALL
++ cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install
++endif
++
++$(TARGETS_C1): $(SUBDIRS_C1)
++ cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS)
++ cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma
++ifdef INSTALL
++ cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install
++endif
++
++$(TARGETS_CORE): $(SUBDIRS_CORE)
++ cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS)
++ cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma
++ifdef INSTALL
++ cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
++endif
++
++$(TARGETS_ZERO): $(SUBDIRS_ZERO)
++ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS)
++ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma
++ifdef INSTALL
++ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
++endif
++
++$(TARGETS_SHARK): $(SUBDIRS_SHARK)
++ cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS)
++ cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma
++ifdef INSTALL
++ cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
++endif
++
++# Just build the tree, and nothing else:
++tree: $(SUBDIRS_C2)
++tree1: $(SUBDIRS_C1)
++treecore: $(SUBDIRS_CORE)
++treezero: $(SUBDIRS_ZERO)
++treeshark: $(SUBDIRS_SHARK)
++
++# Doc target. This is the same for all build options.
++# Hence create a docs directory beside ...$(ARCH)_[...]
++docs: checks
++ $(QUIETLY) mkdir -p $(SUBDIR_DOCS)
++ $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/makefiles/jvmti.make $(MFLAGS) $(BUILDTREE_VARS) JvmtiOutDir=$(SUBDIR_DOCS) jvmtidocs
++
++# Synonyms for win32-like targets.
++compiler2: jvmg product
++
++compiler1: jvmg1 product1
++
++core: jvmgcore productcore
++
++zero: jvmgzero productzero
++
++shark: jvmgshark productshark
++
++clean_docs:
++ rm -rf $(SUBDIR_DOCS)
++
++clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark:
++ rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
++
++clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_shark clean_docs
++
++include $(GAMMADIR)/make/cscope.make
++
++#-------------------------------------------------------------------------------
++
++.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK)
++.PHONY: tree tree1 treecore treezero treeshark
++.PHONY: all compiler1 compiler2 core zero shark
++.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
++.PHONY: checks check_os_version check_j2se_version
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/adjust-mflags.sh openjdk/hotspot/make/bsd/makefiles/adjust-mflags.sh
+--- openjdk.orig/hotspot/make/bsd/makefiles/adjust-mflags.sh 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/adjust-mflags.sh 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,87 @@
++#! /bin/sh
++#
++# Copyright (c) 1999, 2008, 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 script is used only from top.make.
++# The macro $(MFLAGS-adjusted) calls this script to
++# adjust the "-j" arguments to take into account
++# the HOTSPOT_BUILD_JOBS variable. The default
++# handling of the "-j" argument by gnumake does
++# not meet our needs, so we must adjust it ourselves.
++
++# This argument adjustment applies to two recursive
++# calls to "$(MAKE) $(MFLAGS-adjusted)" in top.make.
++# One invokes adlc.make, and the other invokes vm.make.
++# The adjustment propagates the desired concurrency
++# level down to the sub-make (of the adlc or vm).
++# The default behavior of gnumake is to run all
++# sub-makes without concurrency ("-j1").
++
++# Also, we use a make variable rather than an explicit
++# "-j<N>" argument to control this setting, so that
++# the concurrency setting (which must be tuned separately
++# for each MP system) can be set via an environment variable.
++# The recommended setting is 1.5x to 2x the number of available
++# CPUs on the MP system, which is large enough to keep the CPUs
++# busy (even though some jobs may be I/O bound) but not too large,
++# we may presume, to overflow the system's swap space.
++
++set -eu
++
++default_build_jobs=4
++
++case $# in
++[12]) true;;
++*) >&2 echo "Usage: $0 ${MFLAGS} ${HOTSPOT_BUILD_JOBS}"; exit 2;;
++esac
++
++MFLAGS=$1
++HOTSPOT_BUILD_JOBS=${2-}
++
++# Normalize any -jN argument to the form " -j${HBJ}"
++MFLAGS=`
++ echo "$MFLAGS" \
++ | sed '
++ s/^-/ -/
++ s/ -\([^ ][^ ]*\)j/ -\1 -j/
++ s/ -j[0-9][0-9]*/ -j/
++ s/ -j\([^ ]\)/ -j -\1/
++ s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
++ ' `
++
++case ${HOTSPOT_BUILD_JOBS} in \
++
++'') case ${MFLAGS} in
++ *\ -j*)
++ >&2 echo "# Note: -jN is ineffective for setting parallelism in this makefile."
++ >&2 echo "# please set HOTSPOT_BUILD_JOBS=${default_build_jobs} in the command line or environment."
++ esac;;
++
++?*) case ${MFLAGS} in
++ *\ -j*) true;;
++ *) MFLAGS="-j${HOTSPOT_BUILD_JOBS} ${MFLAGS}";;
++ esac;;
++esac
++
++echo "${MFLAGS}"
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/adlc.make openjdk/hotspot/make/bsd/makefiles/adlc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/adlc.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/adlc.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,226 @@
++#
++# Copyright (c) 1999, 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 makefile (adlc.make) is included from the adlc.make in the
++# build directories.
++# It knows how to compile, link, and run the adlc.
++
++include $(GAMMADIR)/make/$(Platform_os_family)/makefiles/rules.make
++
++# #########################################################################
++
++# OUTDIR must be the same as AD_Dir = $(GENERATED)/adfiles in top.make:
++GENERATED = ../generated
++OUTDIR = $(GENERATED)/adfiles
++
++ARCH = $(Platform_arch)
++OS = $(Platform_os_family)
++
++SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad
++
++SOURCES.AD = \
++ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
++ $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
++
++EXEC = $(OUTDIR)/adlc
++
++# set VPATH so make knows where to look for source files
++Src_Dirs_V += $(GAMMADIR)/src/share/vm/adlc
++VPATH += $(Src_Dirs_V:%=%:)
++
++# set INCLUDES for C preprocessor
++Src_Dirs_I += $(GAMMADIR)/src/share/vm/adlc $(GENERATED)
++INCLUDES += $(Src_Dirs_I:%=-I%)
++
++# set flags for adlc compilation
++CPPFLAGS = $(SYSDEFS) $(INCLUDES)
++
++# Force assertions on.
++CPPFLAGS += -DASSERT
++
++# CFLAGS_WARN holds compiler options to suppress/enable warnings.
++# Compiler warnings are treated as errors
++CFLAGS_WARN = -Werror
++CFLAGS += $(CFLAGS_WARN)
++
++OBJECTNAMES = \
++ adlparse.o \
++ archDesc.o \
++ arena.o \
++ dfa.o \
++ dict2.o \
++ filebuff.o \
++ forms.o \
++ formsopt.o \
++ formssel.o \
++ main.o \
++ adlc-opcodes.o \
++ output_c.o \
++ output_h.o \
++
++OBJECTS = $(OBJECTNAMES:%=$(OUTDIR)/%)
++
++GENERATEDNAMES = \
++ ad_$(Platform_arch_model).cpp \
++ ad_$(Platform_arch_model).hpp \
++ ad_$(Platform_arch_model)_clone.cpp \
++ ad_$(Platform_arch_model)_expand.cpp \
++ ad_$(Platform_arch_model)_format.cpp \
++ ad_$(Platform_arch_model)_gen.cpp \
++ ad_$(Platform_arch_model)_misc.cpp \
++ ad_$(Platform_arch_model)_peephole.cpp \
++ ad_$(Platform_arch_model)_pipeline.cpp \
++ adGlobals_$(Platform_arch_model).hpp \
++ dfa_$(Platform_arch_model).cpp \
++
++GENERATEDFILES = $(GENERATEDNAMES:%=$(OUTDIR)/%)
++
++# #########################################################################
++
++all: $(EXEC)
++
++$(EXEC) : $(OBJECTS)
++ @echo Making adlc
++ $(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS)
++
++# Random dependencies:
++$(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp
++
++# The source files refer to ostream.h, which sparcworks calls iostream.h
++$(OBJECTS): ostream.h
++
++ostream.h :
++ @echo >$@ '#include <iostream.h>'
++
++dump:
++ : OUTDIR=$(OUTDIR)
++ : OBJECTS=$(OBJECTS)
++ : products = $(GENERATEDFILES)
++
++all: $(GENERATEDFILES)
++
++$(GENERATEDFILES): refresh_adfiles
++
++# Get a unique temporary directory name, so multiple makes can run in parallel.
++# Note that product files are updated via "mv", which is atomic.
++TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$)
++
++# Debuggable by default
++CFLAGS += -g
++
++# Pass -D flags into ADLC.
++ADLCFLAGS += $(SYSDEFS)
++
++# Note "+="; it is a hook so flags.make can add more flags, like -g or -DFOO.
++ADLCFLAGS += -q -T
++
++# Normally, debugging is done directly on the ad_<arch>*.cpp files.
++# But -g will put #line directives in those files pointing back to <arch>.ad.
++# Some builds of gcc 3.2 have a bug that gets tickled by the extra #line directives
++# so skip it for 3.2 and ealier.
++ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
++ADLCFLAGS += -g
++endif
++
++ifdef LP64
++ADLCFLAGS += -D_LP64
++else
++ADLCFLAGS += -U_LP64
++endif
++
++#
++# adlc_updater is a simple sh script, under sccs control. It is
++# used to selectively update generated adlc files. This should
++# provide a nice compilation speed improvement.
++#
++ADLC_UPDATER_DIRECTORY = $(GAMMADIR)/make/$(OS)
++ADLC_UPDATER = adlc_updater
++$(ADLC_UPDATER): $(ADLC_UPDATER_DIRECTORY)/$(ADLC_UPDATER)
++ $(QUIETLY) cp $< $@; chmod +x $@
++
++# This action refreshes all generated adlc files simultaneously.
++# The way it works is this:
++# 1) create a scratch directory to work in.
++# 2) if the current working directory does not have $(ADLC_UPDATER), copy it.
++# 3) run the compiled adlc executable. This will create new adlc files in the scratch directory.
++# 4) call $(ADLC_UPDATER) on each generated adlc file. It will selectively update changed or missing files.
++# 5) If we actually updated any files, echo a notice.
++#
++refresh_adfiles: $(EXEC) $(SOURCE.AD) $(ADLC_UPDATER)
++ @rm -rf $(TEMPDIR); mkdir $(TEMPDIR)
++ $(QUIETLY) $(EXEC) $(ADLCFLAGS) $(SOURCE.AD) \
++ -c$(TEMPDIR)/ad_$(Platform_arch_model).cpp -h$(TEMPDIR)/ad_$(Platform_arch_model).hpp -a$(TEMPDIR)/dfa_$(Platform_arch_model).cpp -v$(TEMPDIR)/adGlobals_$(Platform_arch_model).hpp \
++ || { rm -rf $(TEMPDIR); exit 1; }
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model).cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model).hpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_clone.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_expand.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_format.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_gen.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_misc.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_peephole.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) ad_$(Platform_arch_model)_pipeline.cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) adGlobals_$(Platform_arch_model).hpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) ./$(ADLC_UPDATER) dfa_$(Platform_arch_model).cpp $(TEMPDIR) $(OUTDIR)
++ $(QUIETLY) [ -f $(TEMPDIR)/made-change ] \
++ || echo "Rescanned $(SOURCE.AD) but encountered no changes."
++ $(QUIETLY) rm -rf $(TEMPDIR)
++
++
++# #########################################################################
++
++$(SOURCE.AD): $(SOURCES.AD)
++ $(QUIETLY) $(PROCESS_AD_FILES) $(SOURCES.AD) > $(SOURCE.AD)
++
++#PROCESS_AD_FILES = cat
++# Pass through #line directives, in case user enables -g option above:
++PROCESS_AD_FILES = awk '{ \
++ if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \
++ if (need_lineno && $$0 !~ /\/\//) \
++ { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \
++ print }'
++
++$(OUTDIR)/%.o: %.cpp
++ @echo Compiling $<
++ $(QUIETLY) $(REMOVE_TARGET)
++ $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
++
++# Some object files are given a prefix, to disambiguate
++# them from objects of the same name built for the VM.
++$(OUTDIR)/adlc-%.o: %.cpp
++ @echo Compiling $<
++ $(QUIETLY) $(REMOVE_TARGET)
++ $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE)
++
++# #########################################################################
++
++clean :
++ rm $(OBJECTS)
++
++cleanall :
++ rm $(OBJECTS) $(EXEC)
++
++# #########################################################################
++
++.PHONY: all dump refresh_adfiles clean cleanall
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/amd64.make openjdk/hotspot/make/bsd/makefiles/amd64.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/amd64.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/amd64.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,39 @@
++#
++# 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.
++#
++#
++
++# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
++# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
++# Must also specify if CPU is little endian
++CFLAGS += -DVM_LITTLE_ENDIAN
++
++CFLAGS += -D_LP64=1
++
++# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
++ifndef USE_SUNCC
++ CFLAGS += -fno-omit-frame-pointer
++endif
++
++OPT_CFLAGS/compactingPermGenGen.o = -O1
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/arm.make openjdk/hotspot/make/bsd/makefiles/arm.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/arm.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/arm.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,29 @@
++#
++# Copyright (c) 2008, 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.
++#
++#
++
++Obj_Files += bsd_arm.o
++
++LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a
++
++CFLAGS += -DVM_LITTLE_ENDIAN
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/buildtree.make openjdk/hotspot/make/bsd/makefiles/buildtree.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/buildtree.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/buildtree.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,409 @@
++#
++# Copyright (c) 2005, 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.
++#
++#
++
++# Usage:
++#
++# $(MAKE) -f buildtree.make SRCARCH=srcarch BUILDARCH=buildarch LIBARCH=libarch
++# GAMMADIR=dir OS_FAMILY=os VARIANT=variant
++#
++# The macros ARCH, GAMMADIR, OS_FAMILY and VARIANT must be defined in the
++# environment or on the command-line:
++#
++# ARCH - sparc, i486, ... HotSpot cpu and os_cpu source directory
++# BUILDARCH - build directory
++# LIBARCH - the corresponding directory in JDK/JRE
++# GAMMADIR - top of workspace
++# OS_FAMILY - operating system
++# VARIANT - core, compiler1, compiler2, or tiered
++# HOTSPOT_RELEASE_VERSION - <major>.<minor>-b<nn> (11.0-b07)
++# HOTSPOT_BUILD_VERSION - internal, internal-$(USER_RELEASE_SUFFIX) or empty
++# JRE_RELEASE_VERSION - <major>.<minor>.<micro> (1.7.0)
++#
++# Builds the directory trees with makefiles plus some convenience files in
++# each directory:
++#
++# Makefile - for "make foo"
++# flags.make - with macro settings
++# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
++# adlc.make -
++# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
++# sa.make - generate SA jar file and natives
++# env.[ck]sh - environment settings
++# test_gamma - script to run the Queens program
++#
++# The makefiles are split this way so that "make foo" will run faster by not
++# having to read the dependency files for the vm.
++
++include $(GAMMADIR)/make/scm.make
++include $(GAMMADIR)/make/altsrc.make
++
++
++# 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details.
++QUIETLY$(MAKE_VERBOSE) = @
++
++# For now, until the compiler is less wobbly:
++TESTFLAGS = -Xbatch -showversion
++
++ifeq ($(ZERO_BUILD), true)
++ PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
++else
++ ifdef USE_SUNCC
++ PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
++ else
++ PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH)
++ endif
++endif
++
++# Allow overriding of the arch part of the directory but default
++# to BUILDARCH if nothing is specified
++ifeq ($(VARIANTARCH),)
++ VARIANTARCH=$(BUILDARCH)
++endif
++
++ifdef FORCE_TIERED
++ifeq ($(VARIANT),tiered)
++PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_compiler2
++else
++PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT)
++endif
++else
++PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT)
++endif
++
++#
++# We do two levels of exclusion in the shared directory.
++# TOPLEVEL excludes are pruned, they are not recursively searched,
++# but lower level directories can be named without fear of collision.
++# ALWAYS excludes are excluded at any level in the directory tree.
++#
++
++ALWAYS_EXCLUDE_DIRS = $(SCM_DIRS)
++
++ifeq ($(VARIANT),tiered)
++TOPLEVEL_EXCLUDE_DIRS = $(ALWAYS_EXCLUDE_DIRS) -o -name adlc -o -name agent
++else
++ifeq ($(VARIANT),compiler2)
++TOPLEVEL_EXCLUDE_DIRS = $(ALWAYS_EXCLUDE_DIRS) -o -name adlc -o -name c1 -o -name agent
++else
++# compiler1 and core use the same exclude list
++TOPLEVEL_EXCLUDE_DIRS = $(ALWAYS_EXCLUDE_DIRS) -o -name adlc -o -name opto -o -name libadt -o -name agent
++endif
++endif
++
++# Get things from the platform file.
++COMPILER = $(shell sed -n 's/^compiler[ ]*=[ ]*//p' $(PLATFORM_FILE))
++
++SIMPLE_DIRS = \
++ $(PLATFORM_DIR)/generated/dependencies \
++ $(PLATFORM_DIR)/generated/adfiles \
++ $(PLATFORM_DIR)/generated/jvmtifiles
++
++TARGETS = debug fastdebug jvmg optimized product profiled
++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 \
++ env.sh env.csh jdkpath.sh .dbxrc test_gamma
++
++BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
++ SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
++
++# Define variables to be set in flags.make.
++# Default values are set in make/defs.make.
++ifeq ($(HOTSPOT_BUILD_VERSION),)
++ HS_BUILD_VER=$(HOTSPOT_RELEASE_VERSION)
++else
++ HS_BUILD_VER=$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)
++endif
++# Set BUILD_USER from system-dependent hints: $LOGNAME, $(whoami)
++ifndef HOTSPOT_BUILD_USER
++ HOTSPOT_BUILD_USER := $(shell echo $$LOGNAME)
++endif
++ifndef HOTSPOT_BUILD_USER
++ HOTSPOT_BUILD_USER := $(shell whoami)
++endif
++# Define HOTSPOT_VM_DISTRO based on settings in make/openjdk_distro
++# or make/hotspot_distro.
++ifndef HOTSPOT_VM_DISTRO
++ ifeq ($(call if-has-altsrc,$(HS_COMMON_SRC)/,true,false),true)
++ include $(GAMMADIR)/make/hotspot_distro
++ else
++ include $(GAMMADIR)/make/openjdk_distro
++ endif
++endif
++
++BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION= JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
++
++BUILDTREE = \
++ $(MAKE) -f $(BUILDTREE_MAKE) $(BUILDTREE_TARGETS) $(BUILDTREE_VARS)
++
++BUILDTREE_COMMENT = echo "\# Generated by $(BUILDTREE_MAKE)"
++
++all: $(SUBMAKE_DIRS)
++
++# Run make in each subdirectory recursively.
++$(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE
++ $(QUIETLY) [ -d $@ ] || { mkdir -p $@; }
++ $(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
++ $(QUIETLY) touch $@
++
++$(SIMPLE_DIRS):
++ $(QUIETLY) mkdir -p $@
++
++# Convenience macro which takes a source relative path, applies $(1) to the
++# absolute path, and then replaces $(GAMMADIR) in the result with a
++# literal "$(GAMMADIR)/" suitable for inclusion in a Makefile.
++gamma-path=$(subst $(GAMMADIR),\$$(GAMMADIR),$(call $(1),$(HS_COMMON_SRC)/$(2)))
++
++flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo; \
++ echo "Platform_file = $(PLATFORM_FILE)" | sed 's|$(GAMMADIR)|$$(GAMMADIR)|'; \
++ sed -n '/=/s/^ */Platform_/p' < $(PLATFORM_FILE); \
++ echo; \
++ echo "GAMMADIR = $(GAMMADIR)"; \
++ echo "SYSDEFS = \$$(Platform_sysdefs)"; \
++ echo "SRCARCH = $(SRCARCH)"; \
++ echo "BUILDARCH = $(BUILDARCH)"; \
++ echo "LIBARCH = $(LIBARCH)"; \
++ echo "TARGET = $(TARGET)"; \
++ echo "HS_BUILD_VER = $(HS_BUILD_VER)"; \
++ echo "JRE_RELEASE_VER = $(JRE_RELEASE_VERSION)"; \
++ echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \
++ echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
++ echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
++ echo; \
++ echo "# Used for platform dispatching"; \
++ echo "TARGET_DEFINES = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
++ echo "TARGET_DEFINES += -DTARGET_ARCH_\$$(Platform_arch)"; \
++ echo "TARGET_DEFINES += -DTARGET_ARCH_MODEL_\$$(Platform_arch_model)"; \
++ echo "TARGET_DEFINES += -DTARGET_OS_ARCH_\$$(Platform_os_arch)"; \
++ echo "TARGET_DEFINES += -DTARGET_OS_ARCH_MODEL_\$$(Platform_os_arch_model)"; \
++ echo "TARGET_DEFINES += -DTARGET_COMPILER_\$$(Platform_compiler)"; \
++ echo "CFLAGS += \$$(TARGET_DEFINES)"; \
++ echo; \
++ echo "Src_Dirs_V = \\"; \
++ sed 's/$$/ \\/;s|$(GAMMADIR)|$$(GAMMADIR)|' ../shared_dirs.lst; \
++ echo "$(call gamma-path,altsrc,cpu/$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
++ echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,os/posix/vm)"; \
++ echo; \
++ echo "Src_Dirs_I = \\"; \
++ echo "$(call gamma-path,altsrc,share/vm/prims) \\"; \
++ echo "$(call gamma-path,commonsrc,share/vm/prims) \\"; \
++ echo "$(call gamma-path,altsrc,share/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,share/vm) \\"; \
++ echo "$(call gamma-path,altsrc,cpu/$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \
++ echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
++ echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
++ echo "$(call gamma-path,commonsrc,os/posix/vm)"; \
++ [ -n "$(CFLAGS_BROWSE)" ] && \
++ echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \
++ [ -n "$(HOTSPOT_EXTRA_SYSDEFS)" ] && \
++ echo && \
++ echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
++ echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
++ echo; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \
++ ) > $@
++
++flags_vm.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo; \
++ [ "$(TARGET)" = profiled ] && \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/optimized.make"; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(TARGET).make"; \
++ ) > $@
++
++../shared_dirs.lst: $(BUILDTREE_MAKE) $(GAMMADIR)/src/share/vm
++ @echo Creating directory list $@
++ $(QUIETLY) if [ -d $(HS_ALT_SRC)/share/vm ]; then \
++ find $(HS_ALT_SRC)/share/vm/* -prune \
++ -type d \! \( $(TOPLEVEL_EXCLUDE_DIRS) \) -exec find {} \
++ \( $(ALWAYS_EXCLUDE_DIRS) \) -prune -o -type d -print \; > $@; \
++ fi;
++ $(QUIETLY) find $(HS_COMMON_SRC)/share/vm/* -prune \
++ -type d \! \( $(TOPLEVEL_EXCLUDE_DIRS) \) -exec find {} \
++ \( $(ALWAYS_EXCLUDE_DIRS) \) -prune -o -type d -print \; >> $@
++
++Makefile: $(BUILDTREE_MAKE)
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo; \
++ echo include flags.make; \
++ echo; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/top.make"; \
++ ) > $@
++
++vm.make: $(BUILDTREE_MAKE)
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo; \
++ echo include flags.make; \
++ echo include flags_vm.make; \
++ echo; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
++ ) > $@
++
++adlc.make: $(BUILDTREE_MAKE)
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo; \
++ echo include flags.make; \
++ echo; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
++ ) > $@
++
++jvmti.make: $(BUILDTREE_MAKE)
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo; \
++ echo include flags.make; \
++ echo; \
++ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
++ ) > $@
++
++sa.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) ( \
++ $(BUILDTREE_COMMENT); \
++ [ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \
++ { \
++ echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
++ echo "DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \
++ echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \
++ } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \
++ echo "HOTSPOT_BUILD_USER=\"$${LOGNAME:-$$USER} in `basename $(GAMMADIR)`\""; \
++ echo "export JAVA_HOME LD_LIBRARY_PATH DYLD_LIBRARY_PATH CLASSPATH HOTSPOT_BUILD_USER"; \
++ ) > $@
++
++env.csh: env.sh
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ [ -n "$$JAVA_HOME" ] && \
++ { echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \
++ sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
++ ) > $@
++
++jdkpath.sh: $(BUILDTREE_MAKE)
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ $(BUILDTREE_COMMENT); \
++ echo "JDK=${JAVA_HOME}"; \
++ ) > $@
++
++.dbxrc: $(BUILDTREE_MAKE)
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \
++ echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \
++ echo "then"; \
++ echo " source \"\$${HOTSPOT_DBXWARE}\""; \
++ echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \
++ echo "then"; \
++ echo " source \"\$$HOME/.dbxrc\""; \
++ echo "fi"; \
++ ) > $@
++
++# Skip the test for product builds (which only work when installed in a JDK), to
++# avoid exiting with an error and causing make to halt.
++NO_TEST_MSG = \
++ echo "$@: skipping the test--this build must be tested in a JDK."
++
++NO_JAVA_HOME_MSG = \
++ echo "JAVA_HOME must be set to run this test."
++
++DATA_MODE = $(DATA_MODE/$(BUILDARCH))
++JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE))
++
++DATA_MODE/i486 = 32
++DATA_MODE/sparc = 32
++DATA_MODE/sparcv9 = 64
++DATA_MODE/amd64 = 64
++DATA_MODE/ia64 = 64
++DATA_MODE/zero = $(ARCH_DATA_MODEL)
++
++JAVA_FLAG/32 = -d32
++JAVA_FLAG/64 = -d64
++
++WRONG_DATA_MODE_MSG = \
++ echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
++
++CROSS_COMPILING_MSG = \
++ echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run."
++
++test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
++ @echo Creating $@ ...
++ $(QUIETLY) ( \
++ 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"; \
++ echo "then"; \
++ echo " $(WRONG_DATA_MODE_MSG); exit 0;"; \
++ echo "fi"; \
++ echo "rm -f Queens.class"; \
++ 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'; \
++ ) > $@
++ $(QUIETLY) chmod +x $@
++
++FORCE:
++
++.PHONY: all FORCE
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/build_vm_def.sh openjdk/hotspot/make/bsd/makefiles/build_vm_def.sh
+--- openjdk.orig/hotspot/make/bsd/makefiles/build_vm_def.sh 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/build_vm_def.sh 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,12 @@
++#!/bin/sh
++
++# If we're cross compiling use that path for nm
++if [ "$CROSS_COMPILE_ARCH" != "" ]; then
++NM=$ALT_COMPILER_PATH/nm
++else
++NM=nm
++fi
++
++$NM --defined-only $* | awk '
++ { if ($3 ~ /^_ZTV/ || $3 ~ /^gHotSpotVM/) print "\t" $3 ";" }
++ '
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/compiler1.make openjdk/hotspot/make/bsd/makefiles/compiler1.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/compiler1.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/compiler1.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,31 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making client version of VM
++
++TYPE=COMPILER1
++
++VM_SUBDIR = client
++
++CFLAGS += -DCOMPILER1
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/compiler2.make openjdk/hotspot/make/bsd/makefiles/compiler2.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/compiler2.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/compiler2.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,31 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making server version of VM
++
++TYPE=COMPILER2
++
++VM_SUBDIR = server
++
++CFLAGS += -DCOMPILER2
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/core.make openjdk/hotspot/make/bsd/makefiles/core.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/core.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/core.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,33 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++# Sets make macros for making core version of VM
++
++# Select which files to use (in top.make)
++TYPE=CORE
++
++# There is no "core" directory in JDK. Install core build in server directory.
++VM_SUBDIR = server
++
++# Note: macros.hpp defines CORE
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/cscope.make openjdk/hotspot/make/bsd/makefiles/cscope.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/cscope.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/cscope.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,160 @@
++#
++# Copyright (c) 2005, 2008, 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.
++#
++#
++
++#
++# The cscope.out file is made in the current directory and spans the entire
++# source tree.
++#
++# Things to note:
++# 1. We use relative names for cscope.
++# 2. We *don't* remove the old cscope.out file, because cscope is smart
++# enough to only build what has changed. It can be confused, however,
++# if files are renamed or removed, so it may be necessary to manually
++# remove cscope.out if a lot of reorganization has occurred.
++#
++
++include $(GAMMADIR)/make/scm.make
++
++NAWK = awk
++RM = rm -f
++HG = hg
++CS_TOP = ../..
++
++CSDIRS = $(CS_TOP)/src $(CS_TOP)/build
++CSINCS = $(CSDIRS:%=-I%)
++
++CSCOPE = cscope
++CSCOPE_FLAGS = -b
++
++# Allow .java files to be added from the environment (CSCLASSES=yes).
++ifdef CSCLASSES
++ADDCLASSES= -o -name '*.java'
++endif
++
++# Adding CClassHeaders also pushes the file count of a full workspace up about
++# 200 files (these files also don't exist in a new workspace, and thus will
++# cause the recreation of the database as they get created, which might seem
++# a little confusing). Thus allow these files to be added from the environment
++# (CSHEADERS=yes).
++ifndef CSHEADERS
++RMCCHEADERS= -o -name CClassHeaders
++endif
++
++# Use CS_GENERATED=x to include auto-generated files in the build directories.
++ifdef CS_GENERATED
++CS_ADD_GENERATED = -o -name '*.incl'
++else
++CS_PRUNE_GENERATED = -o -name '${OS}_*_core' -o -name '${OS}_*_compiler?'
++endif
++
++# OS-specific files for other systems are excluded by default. Use CS_OS=yes
++# to include platform-specific files for other platforms.
++ifndef CS_OS
++CS_OS = linux macos solaris win32 bsd
++CS_PRUNE_OS = $(patsubst %,-o -name '*%*',$(filter-out ${OS},${CS_OS}))
++endif
++
++# Processor-specific files for other processors are excluded by default. Use
++# CS_CPU=x to include platform-specific files for other platforms.
++ifndef CS_CPU
++CS_CPU = i486 sparc amd64 ia64
++CS_PRUNE_CPU = $(patsubst %,-o -name '*%*',$(filter-out ${SRCARCH},${CS_CPU}))
++endif
++
++# What files should we include? A simple rule might be just those files under
++# SCCS control, however this would miss files we create like the opcodes and
++# CClassHeaders. The following attempts to find everything that is *useful*.
++# (.del files are created by sccsrm, demo directories contain many .java files
++# that probably aren't useful for development, and the pkgarchive may contain
++# duplicates of files within the source hierarchy).
++
++# Directories to exclude.
++CS_PRUNE_STD = $(SCM_DIRS) \
++ -o -name '.del-*' \
++ -o -name '*demo' \
++ -o -name pkgarchive
++
++CS_PRUNE = $(CS_PRUNE_STD) \
++ $(CS_PRUNE_OS) \
++ $(CS_PRUNE_CPU) \
++ $(CS_PRUNE_GENERATED) \
++ $(RMCCHEADERS)
++
++# File names to include.
++CSFILENAMES = -name '*.[ch]pp' \
++ -o -name '*.[Ccshlxy]' \
++ $(CS_ADD_GENERATED) \
++ -o -name '*.il' \
++ -o -name '*.cc' \
++ -o -name '*[Mm]akefile*' \
++ -o -name '*.gmk' \
++ -o -name '*.make' \
++ -o -name '*.ad' \
++ $(ADDCLASSES)
++
++.PRECIOUS: cscope.out
++
++cscope cscope.out: cscope.files FORCE
++ $(CSCOPE) $(CSCOPE_FLAGS)
++
++# The .raw file is reordered here in an attempt to make cscope display the most
++# relevant files first.
++cscope.files: .cscope.files.raw
++ echo "$(CSINCS)" > $@
++ -egrep -v "\.java|\/make\/" $< >> $@
++ -fgrep ".java" $< >> $@
++ -fgrep "/make/" $< >> $@
++
++.cscope.files.raw: .nametable.files
++ -find $(CSDIRS) -type d \( $(CS_PRUNE) \) -prune -o \
++ -type f \( $(CSFILENAMES) \) -print > $@
++
++cscope.clean: nametable.clean
++ -$(RM) cscope.out cscope.files .cscope.files.raw
++
++TAGS: cscope.files FORCE
++ egrep -v '^-|^$$' $< | etags --members -
++
++TAGS.clean: nametable.clean
++ -$(RM) TAGS
++
++# .nametable.files and .nametable.files.tmp are used to determine if any files
++# were added to/deleted from/renamed in the workspace. If not, then there's
++# normally no need to rebuild the cscope database. To force a rebuild of
++# the cscope database: gmake nametable.clean.
++.nametable.files: .nametable.files.tmp
++ ( cmp -s $@ $< ) || ( cp $< $@ )
++ -$(RM) $<
++
++# `hg status' is slightly faster than `hg fstatus'. Both are
++# quite a bit slower on an NFS mounted file system, so this is
++# really geared towards repos on local file systems.
++.nametable.files.tmp:
++ -$(HG) fstatus -acmn > $@
++nametable.clean:
++ -$(RM) .nametable.files .nametable.files.tmp
++
++FORCE:
++
++.PHONY: cscope cscope.clean TAGS.clean nametable.clean FORCE
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/debug.make openjdk/hotspot/make/bsd/makefiles/debug.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/debug.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/debug.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,44 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making debug version of VM
++
++# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
++DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
++DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
++CFLAGS += $(DEBUG_CFLAGS/BYFILE)
++
++# Linker mapfile
++MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
++
++_JUNK_ := $(shell echo -e >&2 ""\
++ "----------------------------------------------------------------------\n" \
++ "WARNING: 'make debug' is deprecated. It will be removed in the future.\n" \
++ "Please use 'make jvmg' to build debug JVM. \n" \
++ "----------------------------------------------------------------------\n")
++
++G_SUFFIX = _g
++VERSION = debug
++SYSDEFS += -DASSERT -DDEBUG
++PICFLAGS = DEFAULT
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/defs.make openjdk/hotspot/make/bsd/makefiles/defs.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/defs.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/defs.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,170 @@
++#
++# 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.
++#
++#
++
++# The common definitions for hotspot bsd builds.
++# Include the top level defs.make under make directory instead of this one.
++# This file is included into make/defs.make.
++
++SLASH_JAVA ?= /java
++
++# Need PLATFORM (os-arch combo names) for jdk and hotspot, plus libarch name
++ARCH:=$(shell uname -m)
++PATH_SEP = :
++ifeq ($(LP64), 1)
++ ARCH_DATA_MODEL ?= 64
++else
++ ARCH_DATA_MODEL ?= 32
++endif
++
++# zero
++ifeq ($(ZERO_BUILD), true)
++ ifeq ($(ARCH_DATA_MODEL), 64)
++ MAKE_ARGS += LP64=1
++ endif
++ PLATFORM = bsd-zero
++ VM_PLATFORM = bsd_$(subst i386,i486,$(ZERO_LIBARCH))
++ HS_ARCH = zero
++ ARCH = zero
++endif
++
++# ia64
++ifeq ($(ARCH), ia64)
++ ARCH_DATA_MODEL = 64
++ MAKE_ARGS += LP64=1
++ PLATFORM = bsd-ia64
++ VM_PLATFORM = bsd_ia64
++ HS_ARCH = ia64
++endif
++
++# sparc
++ifeq ($(ARCH), sparc64)
++ ifeq ($(ARCH_DATA_MODEL), 64)
++ ARCH_DATA_MODEL = 64
++ MAKE_ARGS += LP64=1
++ PLATFORM = bsd-sparcv9
++ VM_PLATFORM = bsd_sparcv9
++ else
++ ARCH_DATA_MODEL = 32
++ PLATFORM = bsd-sparc
++ VM_PLATFORM = bsd_sparc
++ endif
++ HS_ARCH = sparc
++endif
++
++# amd64
++ifneq (,$(findstring $(ARCH), amd64 x86_64))
++ ifeq ($(ARCH_DATA_MODEL), 64)
++ ARCH_DATA_MODEL = 64
++ MAKE_ARGS += LP64=1
++ PLATFORM = bsd-amd64
++ VM_PLATFORM = bsd_amd64
++ HS_ARCH = x86
++ else
++ ARCH_DATA_MODEL = 32
++ PLATFORM = bsd-i586
++ VM_PLATFORM = bsd_i486
++ HS_ARCH = x86
++ # We have to reset ARCH to i386 since SRCARCH relies on it
++ ARCH = i386
++ endif
++endif
++
++# i386
++ifeq ($(ARCH), i386)
++ ifeq ($(ARCH_DATA_MODEL), 64)
++ ARCH_DATA_MODEL = 64
++ MAKE_ARGS += LP64=1
++ PLATFORM = bsd-amd64
++ VM_PLATFORM = bsd_amd64
++ HS_ARCH = x86
++ # We have to reset ARCH to amd64 since SRCARCH relies on it
++ ARCH = amd64
++ else
++ ARCH_DATA_MODEL = 32
++ PLATFORM = bsd-i586
++ VM_PLATFORM = bsd_i486
++ HS_ARCH = x86
++ endif
++endif
++
++# ARM
++ifeq ($(ARCH), arm)
++ ARCH_DATA_MODEL = 32
++ PLATFORM = bsd-arm
++ VM_PLATFORM = bsd_arm
++ HS_ARCH = arm
++endif
++
++# PPC
++ifeq ($(ARCH), ppc)
++ ARCH_DATA_MODEL = 32
++ PLATFORM = bsd-ppc
++ VM_PLATFORM = bsd_ppc
++ HS_ARCH = ppc
++endif
++
++JDK_INCLUDE_SUBDIR=bsd
++
++# Library suffix
++OS_VENDOR:=$(shell uname -s)
++ifeq ($(OS_VENDOR),Darwin)
++ LIBRARY_SUFFIX=dylib
++else
++ LIBRARY_SUFFIX=so
++endif
++
++# FIXUP: The subdirectory for a debug build is NOT the same on all platforms
++VM_DEBUG=jvmg
++
++EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
++
++# client and server subdirectories have symbolic links to ../libjsig.so
++EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
++EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
++
++ifndef BUILD_CLIENT_ONLY
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
++endif
++
++ifneq ($(ZERO_BUILD), true)
++ ifeq ($(ARCH_DATA_MODEL), 32)
++ EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
++ endif
++endif
++
++# Serviceability Binaries
++# No SA Support for PPC, IA64, ARM or zero
++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/ppc =
++ADD_SA_BINARIES/ia64 =
++ADD_SA_BINARIES/arm =
++ADD_SA_BINARIES/zero =
++
++EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH))
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/dtrace.make openjdk/hotspot/make/bsd/makefiles/dtrace.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/dtrace.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/dtrace.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,27 @@
++#
++# Copyright (c) 2005, 2008, 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.
++#
++#
++
++# Bsd does not build jvm_db
++LIBJVM_DB =
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/fastdebug.make openjdk/hotspot/make/bsd/makefiles/fastdebug.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/fastdebug.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/fastdebug.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,64 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making debug version of VM
++
++# Compiler specific OPT_CFLAGS are passed in from gcc.make, sparcWorks.make
++OPT_CFLAGS/DEFAULT= $(OPT_CFLAGS)
++OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
++
++# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
++
++ifeq ($(BUILDARCH), ia64)
++ # Bug in GCC, causes hang. -O1 will override the -O3 specified earlier
++ OPT_CFLAGS/callGenerator.o += -O1
++ OPT_CFLAGS/ciTypeFlow.o += -O1
++ OPT_CFLAGS/compile.o += -O1
++ OPT_CFLAGS/concurrentMarkSweepGeneration.o += -O1
++ OPT_CFLAGS/doCall.o += -O1
++ OPT_CFLAGS/generateOopMap.o += -O1
++ OPT_CFLAGS/generateOptoStub.o += -O1
++ OPT_CFLAGS/graphKit.o += -O1
++ OPT_CFLAGS/instanceKlass.o += -O1
++ OPT_CFLAGS/interpreterRT_ia64.o += -O1
++ OPT_CFLAGS/output.o += -O1
++ OPT_CFLAGS/parse1.o += -O1
++ OPT_CFLAGS/runtime.o += -O1
++ OPT_CFLAGS/synchronizer.o += -O1
++endif
++
++
++# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
++CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
++
++# Set the environment variable HOTSPARC_GENERIC to "true"
++# to inhibit the effect of the previous line on CFLAGS.
++
++# Linker mapfile
++MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
++
++G_SUFFIX = _g
++VERSION = optimized
++SYSDEFS += -DASSERT -DFASTDEBUG
++PICFLAGS = DEFAULT
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/gcc.make openjdk/hotspot/make/bsd/makefiles/gcc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/gcc.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/gcc.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,267 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++OS_VENDOR = $(shell uname -s)
++
++#------------------------------------------------------------------------
++# CC, CPP & AS
++
++# 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)
++endif
++
++AS = $(CC) -c -x assembler-with-cpp
++
++# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
++# prints the numbers (e.g. "2.95", "3.2.1")
++CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
++CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
++
++# check for precompiled headers support
++ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
++# Allow the user to turn off precompiled headers from the command line.
++ifneq ($(USE_PRECOMPILED_HEADER),0)
++USE_PRECOMPILED_HEADER=1
++PRECOMPILED_HEADER_DIR=.
++PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled.hpp
++PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
++endif
++endif
++
++
++#------------------------------------------------------------------------
++# Compiler flags
++
++# position-independent code
++PICFLAG = -fPIC
++
++VM_PICFLAG/LIBJVM = $(PICFLAG)
++VM_PICFLAG/AOUT =
++VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO))
++
++ifeq ($(ZERO_BUILD), true)
++CFLAGS += $(LIBFFI_CFLAGS)
++endif
++ifeq ($(SHARK_BUILD), true)
++CFLAGS += $(LLVM_CFLAGS)
++endif
++CFLAGS += $(VM_PICFLAG)
++CFLAGS += -fno-rtti
++CFLAGS += -fno-exceptions
++CFLAGS += -pthread
++CFLAGS += -fcheck-new
++# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
++# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
++ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
++CFLAGS += -fvisibility=hidden
++endif
++
++ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
++ARCHFLAG/i486 = -m32 -march=i586
++ARCHFLAG/amd64 = -m64
++ARCHFLAG/ia64 =
++ARCHFLAG/sparc = -m32 -mcpu=v9
++ARCHFLAG/sparcv9 = -m64 -mcpu=v9
++ARCHFLAG/zero = $(ZERO_ARCHFLAG)
++
++# Darwin-specific build flags
++ifeq ($(OS_VENDOR), Darwin)
++ # Ineffecient 16-byte stack re-alignment on Darwin/IA32
++ ARCHFLAG/i486 += -mstackrealign
++endif
++
++CFLAGS += $(ARCHFLAG)
++AOUT_FLAGS += $(ARCHFLAG)
++LFLAGS += $(ARCHFLAG)
++ASFLAGS += $(ARCHFLAG)
++
++ifdef E500V2
++CFLAGS += -DE500V2
++endif
++
++# Use C++ Interpreter
++ifdef CC_INTERP
++ CFLAGS += -DCC_INTERP
++endif
++
++# Build for embedded targets
++ifdef JAVASE_EMBEDDED
++ CFLAGS += -DJAVASE_EMBEDDED
++endif
++
++# Keep temporary files (.ii, .s)
++ifdef NEED_ASM
++ CFLAGS += -save-temps
++else
++ CFLAGS += -pipe
++endif
++
++# Compiler warnings are treated as errors
++WARNINGS_ARE_ERRORS = -Werror
++
++# Except for a few acceptable ones
++# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
++# conversions which might affect the values. To avoid that, we need to turn
++# it off explicitly.
++ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
++ACCEPTABLE_WARNINGS = -Wpointer-arith -Wsign-compare
++else
++ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
++endif
++
++CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS)
++# Special cases
++CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
++# XXXDARWIN: for _dyld_bind_fully_image_containing_address
++ifeq ($(OS_VENDOR), Darwin)
++ CFLAGS_WARN/os_bsd.o = $(CFLAGS_WARN/DEFAULT) -Wno-deprecated-declarations
++endif
++
++
++# The flags to use for an Optimized g++ build
++OPT_CFLAGS += -O3
++
++# Hotspot uses very unstrict aliasing turn this optimization off
++OPT_CFLAGS += -fno-strict-aliasing
++
++# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp
++# if we use expensive-optimizations
++ifeq ($(BUILDARCH), ia64)
++OPT_CFLAGS += -fno-expensive-optimizations
++endif
++
++OPT_CFLAGS/NOOPT=-O0
++
++# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
++ifneq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) = 3 \) \))" "0"
++OPT_CFLAGS/mulnode.o += -O0
++endif
++
++# Flags for generating make dependency flags.
++ifneq ("${CC_VER_MAJOR}", "2")
++DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
++endif
++
++# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
++ifneq ($(USE_PRECOMPILED_HEADER),1)
++CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
++endif
++
++#------------------------------------------------------------------------
++# Linker flags
++
++# statically link libstdc++.so, work with gcc but ignored by g++
++STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
++
++# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
++ifneq ("${CC_VER_MAJOR}", "2")
++STATIC_LIBGCC += -static-libgcc
++endif
++
++ifeq ($(BUILDARCH), ia64)
++LFLAGS += -Wl,-relax
++endif
++
++# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
++MAPFLAG = -Xlinker --version-script=FILENAME
++
++#
++# Shared Library
++#
++ifeq ($(OS_VENDOR), Darwin)
++ # Standard linker flags
++ LFLAGS +=
++
++ # Darwin doesn't use ELF and doesn't support version scripts
++ LDNOMAP = true
++
++ # Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
++ SONAMEFLAG =
++
++ # Build shared library
++ SHARED_FLAG = -dynamiclib $(VM_PICFLAG)
++
++ # Keep symbols even they are not used
++ #AOUT_FLAGS += -Xlinker -export-dynamic
++else
++ # Enable linker optimization
++ LFLAGS += -Xlinker -O1
++
++ # Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
++ SONAMEFLAG = -Xlinker -soname=SONAME
++
++ # Build shared library
++ SHARED_FLAG = -shared $(VM_PICFLAG)
++
++ # Keep symbols even they are not used
++ AOUT_FLAGS += -Xlinker -export-dynamic
++endif
++
++#------------------------------------------------------------------------
++# Debug flags
++
++# Use the stabs format for debugging information (this is the default
++# on gcc-2.91). It's good enough, has all the information about line
++# numbers and local variables, and libjvm_g.so is only about 16M.
++# Change this back to "-g" if you want the most expressive format.
++# (warning: that could easily inflate libjvm_g.so to 150M!)
++# Note: The Itanium gcc compiler crashes when using -gstabs.
++DEBUG_CFLAGS/ia64 = -g
++DEBUG_CFLAGS/amd64 = -g
++DEBUG_CFLAGS/arm = -g
++DEBUG_CFLAGS/ppc = -g
++DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
++ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
++DEBUG_CFLAGS += -gstabs
++endif
++
++# DEBUG_BINARIES overrides everything, use full -g debug information
++ifeq ($(DEBUG_BINARIES), true)
++ DEBUG_CFLAGS = -g
++ CFLAGS += $(DEBUG_CFLAGS)
++endif
++
++# If we are building HEADLESS, pass on to VM
++# so it can set the java.awt.headless property
++ifdef HEADLESS
++CFLAGS += -DHEADLESS
++endif
++
++# We are building Embedded for a small device
++# favor code space over speed
++ifdef MINIMIZE_RAM_USAGE
++CFLAGS += -DMINIMIZE_RAM_USAGE
++endif
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/hp1.make openjdk/hotspot/make/bsd/makefiles/hp1.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/hp1.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/hp1.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,29 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making premium version of VM
++
++TYPE=HP1
++
++CFLAGS += -DCOMPILER1
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/hp.make openjdk/hotspot/make/bsd/makefiles/hp.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/hp.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/hp.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,29 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making premium version of VM
++
++TYPE=HP
++
++CFLAGS += -DCOMPILER2
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/i486.make openjdk/hotspot/make/bsd/makefiles/i486.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/i486.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/i486.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,34 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++# TLS helper, assembled from .s file
++
++# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
++# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
++# Must also specify if CPU is little endian
++CFLAGS += -DVM_LITTLE_ENDIAN
++
++OPT_CFLAGS/compactingPermGenGen.o = -O1
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/ia64.make openjdk/hotspot/make/bsd/makefiles/ia64.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/ia64.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/ia64.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,43 @@
++#
++# Copyright (c) 2005, 2008, 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.
++#
++#
++
++#
++# IA64 only uses c++ based interpreter
++CFLAGS += -DCC_INTERP -D_LP64=1 -DVM_LITTLE_ENDIAN
++# Hotspot uses very unstrict aliasing turn this optimization off
++OPT_CFLAGS += -fno-strict-aliasing
++ifeq ($(VERSION),debug)
++ASM_FLAGS= -DDEBUG
++else
++ASM_FLAGS=
++endif
++# workaround gcc bug in compiling varargs
++OPT_CFLAGS/jni.o = -O0
++
++# gcc/ia64 has a bug that internal gcc functions linked with libjvm.so
++# are made public. Hiding those symbols will cause undefined symbol error
++# when VM is dropped into older JDK. We probably will need an IA64
++# mapfile to include those symbols as a workaround. Disable linker mapfile
++# for now.
++LDNOMAP=true
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/jsig.make openjdk/hotspot/make/bsd/makefiles/jsig.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/jsig.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/jsig.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,67 @@
++#
++# Copyright (c) 2005, 2009, 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.
++#
++#
++
++# Rules to build signal interposition library, used by vm.make
++
++# libjsig[_g].so: signal interposition library
++JSIG = jsig
++JSIG_G = $(JSIG)$(G_SUFFIX)
++
++ifeq ($(OS_VENDOR), Darwin)
++ LIBJSIG = lib$(JSIG).dylib
++ LIBJSIG_G = lib$(JSIG_G).dylib
++else
++ LIBJSIG = lib$(JSIG).so
++ LIBJSIG_G = lib$(JSIG_G).so
++endif
++
++JSIGSRCDIR = $(GAMMADIR)/src/os/$(Platform_os_family)/vm
++
++DEST_JSIG = $(JDK_LIBDIR)/$(LIBJSIG)
++
++LIBJSIG_MAPFILE = $(MAKEFILES_DIR)/mapfile-vers-jsig
++
++# On Bsd we really dont want a mapfile, as this library is small
++# and preloaded using LD_PRELOAD, making functions private will
++# cause problems with interposing. See CR: 6466665
++# LFLAGS_JSIG += $(MAPFLAG:FILENAME=$(LIBJSIG_MAPFILE))
++
++LFLAGS_JSIG += -D_GNU_SOURCE -pthread $(LDFLAGS_HASH_STYLE)
++
++# DEBUG_BINARIES overrides everything, use full -g debug information
++ifeq ($(DEBUG_BINARIES), true)
++ JSIG_DEBUG_CFLAGS = -g
++endif
++
++$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
++ @echo Making signal interposition lib...
++ $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
++ $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $<
++ $(QUIETLY) [ -f $(LIBJSIG_G) ] || { ln -s $@ $(LIBJSIG_G); }
++
++install_jsig: $(LIBJSIG)
++ @echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
++ $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done"
++
++.PHONY: install_jsig
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/jvmg.make openjdk/hotspot/make/bsd/makefiles/jvmg.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/jvmg.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/jvmg.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,41 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making debug version of VM
++
++# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
++DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
++DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
++CFLAGS += $(DEBUG_CFLAGS/BYFILE)
++
++# Set the environment variable HOTSPARC_GENERIC to "true"
++# to inhibit the effect of the previous line on CFLAGS.
++
++# Linker mapfile
++MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
++
++G_SUFFIX = _g
++VERSION = debug
++SYSDEFS += -DASSERT -DDEBUG
++PICFLAGS = DEFAULT
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/jvmti.make openjdk/hotspot/make/bsd/makefiles/jvmti.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/jvmti.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/jvmti.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,117 @@
++#
++# 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.
++#
++#
++
++# This makefile (jvmti.make) is included from the jvmti.make in the
++# build directories.
++#
++# It knows how to build and run the tools to generate jvmti.
++
++include $(GAMMADIR)/make/bsd/makefiles/rules.make
++
++# #########################################################################
++
++TOPDIR = $(shell echo `pwd`)
++GENERATED = $(TOPDIR)/../generated
++JvmtiOutDir = $(GENERATED)/jvmtifiles
++
++JvmtiSrcDir = $(GAMMADIR)/src/share/vm/prims
++InterpreterSrcDir = $(GAMMADIR)/src/share/vm/interpreter
++
++# set VPATH so make knows where to look for source files
++Src_Dirs_V += $(JvmtiSrcDir)
++VPATH += $(Src_Dirs_V:%=%:)
++
++JvmtiGeneratedNames = \
++ jvmtiEnv.hpp \
++ jvmtiEnter.cpp \
++ jvmtiEnterTrace.cpp \
++ jvmtiEnvRecommended.cpp \
++ bytecodeInterpreterWithChecks.cpp \
++ jvmti.h \
++
++JvmtiEnvFillSource = $(JvmtiSrcDir)/jvmtiEnvFill.java
++JvmtiEnvFillClass = $(JvmtiOutDir)/jvmtiEnvFill.class
++
++JvmtiGenSource = $(JvmtiSrcDir)/jvmtiGen.java
++JvmtiGenClass = $(JvmtiOutDir)/jvmtiGen.class
++
++JvmtiGeneratedFiles = $(JvmtiGeneratedNames:%=$(JvmtiOutDir)/%)
++
++XSLT = $(QUIETLY) $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
++
++.PHONY: all jvmtidocs clean cleanall
++
++# #########################################################################
++
++all: $(JvmtiGeneratedFiles)
++
++both = $(JvmtiGenClass) $(JvmtiSrcDir)/jvmti.xml $(JvmtiSrcDir)/jvmtiLib.xsl
++
++$(JvmtiGenClass): $(JvmtiGenSource)
++ $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiGenSource)
++
++$(JvmtiEnvFillClass): $(JvmtiEnvFillSource)
++ $(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -d $(JvmtiOutDir) $(JvmtiEnvFillSource)
++
++$(JvmtiOutDir)/jvmtiEnter.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
++ @echo Generating $@
++ $(XSLT) -IN $(JvmtiSrcDir)/jvmti.xml -XSL $(JvmtiSrcDir)/jvmtiEnter.xsl -OUT $(JvmtiOutDir)/jvmtiEnter.cpp -PARAM interface jvmti
++
++$(JvmtiOutDir)/bytecodeInterpreterWithChecks.cpp: $(JvmtiGenClass) $(InterpreterSrcDir)/bytecodeInterpreter.cpp $(InterpreterSrcDir)/bytecodeInterpreterWithChecks.xml $(InterpreterSrcDir)/bytecodeInterpreterWithChecks.xsl
++ @echo Generating $@
++ $(XSLT) -IN $(InterpreterSrcDir)/bytecodeInterpreterWithChecks.xml -XSL $(InterpreterSrcDir)/bytecodeInterpreterWithChecks.xsl -OUT $(JvmtiOutDir)/bytecodeInterpreterWithChecks.cpp
++
++$(JvmtiOutDir)/jvmtiEnterTrace.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnter.xsl
++ @echo Generating $@
++ $(XSLT) -IN $(JvmtiSrcDir)/jvmti.xml -XSL $(JvmtiSrcDir)/jvmtiEnter.xsl -OUT $(JvmtiOutDir)/jvmtiEnterTrace.cpp -PARAM interface jvmti -PARAM trace Trace
++
++$(JvmtiOutDir)/jvmtiEnvRecommended.cpp: $(both) $(JvmtiSrcDir)/jvmtiEnv.xsl $(JvmtiSrcDir)/jvmtiEnv.cpp $(JvmtiEnvFillClass)
++ @echo Generating $@
++ $(XSLT) -IN $(JvmtiSrcDir)/jvmti.xml -XSL $(JvmtiSrcDir)/jvmtiEnv.xsl -OUT $(JvmtiOutDir)/jvmtiEnvStub.cpp
++ $(QUIETLY) $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiEnvFill $(JvmtiSrcDir)/jvmtiEnv.cpp $(JvmtiOutDir)/jvmtiEnvStub.cpp $(JvmtiOutDir)/jvmtiEnvRecommended.cpp
++
++$(JvmtiOutDir)/jvmtiEnv.hpp: $(both) $(JvmtiSrcDir)/jvmtiHpp.xsl
++ @echo Generating $@
++ $(XSLT) -IN $(JvmtiSrcDir)/jvmti.xml -XSL $(JvmtiSrcDir)/jvmtiHpp.xsl -OUT $(JvmtiOutDir)/jvmtiEnv.hpp
++
++$(JvmtiOutDir)/jvmti.h: $(both) $(JvmtiSrcDir)/jvmtiH.xsl
++ @echo Generating $@
++ $(XSLT) -IN $(JvmtiSrcDir)/jvmti.xml -XSL $(JvmtiSrcDir)/jvmtiH.xsl -OUT $(JvmtiOutDir)/jvmti.h
++
++jvmtidocs: $(JvmtiOutDir)/jvmti.html
++
++$(JvmtiOutDir)/jvmti.html: $(both) $(JvmtiSrcDir)/jvmti.xsl
++ @echo Generating $@
++ $(XSLT) -IN $(JvmtiSrcDir)/jvmti.xml -XSL $(JvmtiSrcDir)/jvmti.xsl -OUT $(JvmtiOutDir)/jvmti.html
++
++# #########################################################################
++
++clean :
++ rm $(JvmtiGenClass) $(JvmtiEnvFillClass) $(JvmtiGeneratedFiles)
++
++cleanall :
++ rm $(JvmtiGenClass) $(JvmtiEnvFillClass) $(JvmtiGeneratedFiles)
++
++# #########################################################################
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/launcher.make openjdk/hotspot/make/bsd/makefiles/launcher.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/launcher.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/launcher.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,93 @@
++#
++# 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.
++#
++#
++
++# Rules to build gamma launcher, used by vm.make
++
++
++LAUNCHER_SCRIPT = hotspot
++LAUNCHER = gamma
++
++LAUNCHERDIR := $(GAMMADIR)/src/os/posix/launcher
++LAUNCHERDIR_SHARE := $(GAMMADIR)/src/share/tools/launcher
++LAUNCHERFLAGS := $(ARCHFLAG) \
++ -I$(LAUNCHERDIR) -I$(GAMMADIR)/src/share/vm/prims \
++ -I$(LAUNCHERDIR_SHARE) \
++ -DFULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
++ -DJDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
++ -DJDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
++ -DARCH=\"$(LIBARCH)\" \
++ -DGAMMA \
++ -DLAUNCHER_TYPE=\"gamma\" \
++ -DLINK_INTO_$(LINK_INTO) \
++ $(TARGET_DEFINES)
++
++ifeq ($(LINK_INTO),AOUT)
++ LAUNCHER.o = launcher.o $(JVM_OBJ_FILES)
++ LAUNCHER_MAPFILE = mapfile_reorder
++ LFLAGS_LAUNCHER$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LAUNCHER_MAPFILE))
++ LFLAGS_LAUNCHER += $(SONAMEFLAG:SONAME=$(LIBJVM)) $(STATIC_LIBGCC)
++ LIBS_LAUNCHER += $(STATIC_STDCXX) $(LIBS)
++else
++ LAUNCHER.o = launcher.o
++ LFLAGS_LAUNCHER += -L`pwd`
++ LIBS_LAUNCHER += -l$(JVM) $(LIBS)
++endif
++
++LINK_LAUNCHER = $(LINK.c)
++
++LINK_LAUNCHER/PRE_HOOK = $(LINK_LIB.CC/PRE_HOOK)
++LINK_LAUNCHER/POST_HOOK = $(LINK_LIB.CC/POST_HOOK)
++
++LAUNCHER_OUT = launcher
++
++SUFFIXES += .d
++
++SOURCES := $(shell find $(LAUNCHERDIR) -name "*.c")
++SOURCES_SHARE := $(shell find $(LAUNCHERDIR_SHARE) -name "*.c")
++
++OBJS := $(patsubst $(LAUNCHERDIR)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES)) $(patsubst $(LAUNCHERDIR_SHARE)/%.c,$(LAUNCHER_OUT)/%.o,$(SOURCES_SHARE))
++
++DEPFILES := $(patsubst %.o,%.d,$(OBJS))
++-include $(DEPFILES)
++
++$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR_SHARE)/%.c
++ $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
++ $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS)
++
++$(LAUNCHER_OUT)/%.o: $(LAUNCHERDIR)/%.c
++ $(QUIETLY) [ -d $(LAUNCHER_OUT) ] || { mkdir -p $(LAUNCHER_OUT); }
++ $(QUIETLY) $(CC) -g -o $@ -c $< -MMD $(LAUNCHERFLAGS) $(CPPFLAGS)
++
++$(LAUNCHER): $(OBJS) $(LIBJVM) $(LAUNCHER_MAPFILE)
++ $(QUIETLY) echo Linking launcher...
++ $(QUIETLY) $(LINK_LAUNCHER/PRE_HOOK)
++ $(QUIETLY) $(LINK_LAUNCHER) $(LFLAGS_LAUNCHER) -o $@ $(OBJS) $(LIBS_LAUNCHER)
++ $(QUIETLY) $(LINK_LAUNCHER/POST_HOOK)
++
++$(LAUNCHER): $(LAUNCHER_SCRIPT)
++
++$(LAUNCHER_SCRIPT): $(LAUNCHERDIR)/launcher.script
++ $(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
++ $(QUIETLY) chmod +x $@
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/mapfile-vers-debug openjdk/hotspot/make/bsd/makefiles/mapfile-vers-debug
+--- openjdk.orig/hotspot/make/bsd/makefiles/mapfile-vers-debug 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/mapfile-vers-debug 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,291 @@
++#
++# @(#)mapfile-vers-debug 1.18 07/10/25 16:47:35
++#
++
++#
++# Copyright (c) 2002, 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.
++#
++#
++
++# Define public interface.
++
++SUNWprivate_1.1 {
++ global:
++ # JNI
++ JNI_CreateJavaVM;
++ JNI_GetCreatedJavaVMs;
++ JNI_GetDefaultJavaVMInitArgs;
++
++ # JVM
++ JVM_Accept;
++ JVM_ActiveProcessorCount;
++ JVM_AllocateNewArray;
++ JVM_AllocateNewObject;
++ JVM_ArrayCopy;
++ JVM_AssertionStatusDirectives;
++ JVM_Available;
++ JVM_Bind;
++ JVM_ClassDepth;
++ JVM_ClassLoaderDepth;
++ JVM_Clone;
++ JVM_Close;
++ JVM_CX8Field;
++ JVM_CompileClass;
++ JVM_CompileClasses;
++ JVM_CompilerCommand;
++ JVM_Connect;
++ JVM_ConstantPoolGetClassAt;
++ JVM_ConstantPoolGetClassAtIfLoaded;
++ JVM_ConstantPoolGetDoubleAt;
++ JVM_ConstantPoolGetFieldAt;
++ JVM_ConstantPoolGetFieldAtIfLoaded;
++ JVM_ConstantPoolGetFloatAt;
++ JVM_ConstantPoolGetIntAt;
++ JVM_ConstantPoolGetLongAt;
++ JVM_ConstantPoolGetMethodAt;
++ JVM_ConstantPoolGetMethodAtIfLoaded;
++ JVM_ConstantPoolGetMemberRefInfoAt;
++ JVM_ConstantPoolGetSize;
++ JVM_ConstantPoolGetStringAt;
++ JVM_ConstantPoolGetUTF8At;
++ JVM_CountStackFrames;
++ JVM_CurrentClassLoader;
++ JVM_CurrentLoadedClass;
++ JVM_CurrentThread;
++ JVM_CurrentTimeMillis;
++ JVM_DefineClass;
++ JVM_DefineClassWithSource;
++ JVM_DefineClassWithSourceCond;
++ JVM_DesiredAssertionStatus;
++ JVM_DisableCompiler;
++ JVM_DoPrivileged;
++ JVM_DTraceGetVersion;
++ JVM_DTraceActivate;
++ JVM_DTraceIsProbeEnabled;
++ JVM_DTraceIsSupported;
++ JVM_DTraceDispose;
++ JVM_DumpAllStacks;
++ JVM_DumpThreads;
++ JVM_EnableCompiler;
++ JVM_Exit;
++ JVM_FillInStackTrace;
++ JVM_FindClassFromClass;
++ JVM_FindClassFromClassLoader;
++ JVM_FindClassFromBootLoader;
++ JVM_FindLibraryEntry;
++ JVM_FindLoadedClass;
++ JVM_FindPrimitiveClass;
++ JVM_FindSignal;
++ JVM_FreeMemory;
++ JVM_GC;
++ JVM_GetAllThreads;
++ JVM_GetArrayElement;
++ JVM_GetArrayLength;
++ JVM_GetCPClassNameUTF;
++ JVM_GetCPFieldClassNameUTF;
++ JVM_GetCPFieldModifiers;
++ JVM_GetCPFieldNameUTF;
++ JVM_GetCPFieldSignatureUTF;
++ JVM_GetCPMethodClassNameUTF;
++ JVM_GetCPMethodModifiers;
++ JVM_GetCPMethodNameUTF;
++ JVM_GetCPMethodSignatureUTF;
++ JVM_GetCallerClass;
++ JVM_GetClassAccessFlags;
++ JVM_GetClassAnnotations;
++ JVM_GetClassCPEntriesCount;
++ JVM_GetClassCPTypes;
++ JVM_GetClassConstantPool;
++ JVM_GetClassContext;
++ JVM_GetClassDeclaredConstructors;
++ JVM_GetClassDeclaredFields;
++ JVM_GetClassDeclaredMethods;
++ JVM_GetClassFieldsCount;
++ JVM_GetClassInterfaces;
++ JVM_GetClassLoader;
++ JVM_GetClassMethodsCount;
++ JVM_GetClassModifiers;
++ JVM_GetClassName;
++ JVM_GetClassNameUTF;
++ JVM_GetClassSignature;
++ JVM_GetClassSigners;
++ JVM_GetComponentType;
++ JVM_GetDeclaredClasses;
++ JVM_GetDeclaringClass;
++ JVM_GetEnclosingMethodInfo;
++ JVM_GetFieldAnnotations;
++ JVM_GetFieldIxModifiers;
++ JVM_GetHostName;
++ JVM_GetInheritedAccessControlContext;
++ JVM_GetInterfaceVersion;
++ JVM_GetLastErrorString;
++ JVM_GetManagement;
++ JVM_GetMethodAnnotations;
++ JVM_GetMethodDefaultAnnotationValue;
++ JVM_GetMethodIxArgsSize;
++ JVM_GetMethodIxByteCode;
++ JVM_GetMethodIxByteCodeLength;
++ JVM_GetMethodIxExceptionIndexes;
++ JVM_GetMethodIxExceptionTableEntry;
++ JVM_GetMethodIxExceptionTableLength;
++ JVM_GetMethodIxExceptionsCount;
++ JVM_GetMethodIxLocalsCount;
++ JVM_GetMethodIxMaxStack;
++ JVM_GetMethodIxModifiers;
++ JVM_GetMethodIxNameUTF;
++ JVM_GetMethodIxSignatureUTF;
++ JVM_GetMethodParameterAnnotations;
++ JVM_GetPrimitiveArrayElement;
++ JVM_GetProtectionDomain;
++ JVM_GetSockName;
++ JVM_GetSockOpt;
++ JVM_GetStackAccessControlContext;
++ JVM_GetStackTraceDepth;
++ JVM_GetStackTraceElement;
++ JVM_GetSystemPackage;
++ JVM_GetSystemPackages;
++ JVM_GetThreadStateNames;
++ JVM_GetThreadStateValues;
++ JVM_GetVersionInfo;
++ JVM_Halt;
++ JVM_HoldsLock;
++ JVM_IHashCode;
++ JVM_InitAgentProperties;
++ JVM_InitProperties;
++ JVM_InitializeCompiler;
++ JVM_InitializeSocketLibrary;
++ JVM_InternString;
++ JVM_Interrupt;
++ JVM_InvokeMethod;
++ JVM_IsArrayClass;
++ JVM_IsConstructorIx;
++ JVM_IsInterface;
++ JVM_IsInterrupted;
++ JVM_IsNaN;
++ JVM_IsPrimitiveClass;
++ JVM_IsSameClassPackage;
++ JVM_IsSilentCompiler;
++ JVM_IsSupportedJNIVersion;
++ JVM_IsThreadAlive;
++ JVM_LatestUserDefinedLoader;
++ JVM_Listen;
++ JVM_LoadClass0;
++ JVM_LoadLibrary;
++ JVM_Lseek;
++ JVM_MaxObjectInspectionAge;
++ JVM_MaxMemory;
++ JVM_MonitorNotify;
++ JVM_MonitorNotifyAll;
++ JVM_MonitorWait;
++ JVM_NanoTime;
++ JVM_NativePath;
++ JVM_NewArray;
++ JVM_NewInstanceFromConstructor;
++ JVM_NewMultiArray;
++ JVM_OnExit;
++ JVM_Open;
++ JVM_PrintStackTrace;
++ JVM_RaiseSignal;
++ JVM_RawMonitorCreate;
++ JVM_RawMonitorDestroy;
++ JVM_RawMonitorEnter;
++ JVM_RawMonitorExit;
++ JVM_Read;
++ JVM_Recv;
++ JVM_RecvFrom;
++ JVM_RegisterSignal;
++ JVM_ReleaseUTF;
++ JVM_ResolveClass;
++ JVM_ResumeThread;
++ JVM_Send;
++ JVM_SendTo;
++ JVM_SetArrayElement;
++ JVM_SetClassSigners;
++ JVM_SetLength;
++ JVM_SetPrimitiveArrayElement;
++ JVM_SetProtectionDomain;
++ JVM_SetSockOpt;
++ JVM_SetThreadPriority;
++ JVM_Sleep;
++ JVM_Socket;
++ JVM_SocketAvailable;
++ JVM_SocketClose;
++ JVM_SocketShutdown;
++ JVM_StartThread;
++ JVM_StopThread;
++ JVM_SuspendThread;
++ JVM_SupportsCX8;
++ JVM_Sync;
++ JVM_Timeout;
++ JVM_TotalMemory;
++ JVM_TraceInstructions;
++ JVM_TraceMethodCalls;
++ JVM_UnloadLibrary;
++ JVM_Write;
++ JVM_Yield;
++ JVM_handle_bsd_signal;
++
++ # Old reflection routines
++ # These do not need to be present in the product build in JDK 1.4
++ # but their code has not been removed yet because there will not
++ # be a substantial code savings until JVM_InvokeMethod and
++ # JVM_NewInstanceFromConstructor can also be removed; see
++ # reflectionCompat.hpp.
++ JVM_GetClassConstructor;
++ JVM_GetClassConstructors;
++ JVM_GetClassField;
++ JVM_GetClassFields;
++ JVM_GetClassMethod;
++ JVM_GetClassMethods;
++ JVM_GetField;
++ JVM_GetPrimitiveField;
++ JVM_NewInstance;
++ JVM_SetField;
++ JVM_SetPrimitiveField;
++
++ # debug JVM
++ JVM_AccessVMBooleanFlag;
++ JVM_AccessVMIntFlag;
++ JVM_VMBreakPoint;
++
++ # miscellaneous functions
++ jio_fprintf;
++ jio_printf;
++ jio_snprintf;
++ jio_vfprintf;
++ jio_vsnprintf;
++ fork1;
++ numa_warn;
++ numa_error;
++
++ # Needed because there is no JVM interface for this.
++ sysThreadAvailableStackWithSlack;
++
++ # This is for Forte Analyzer profiling support.
++ AsyncGetCallTrace;
++
++ # INSERT VTABLE SYMBOLS HERE
++
++ local:
++ *;
++};
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/mapfile-vers-jsig openjdk/hotspot/make/bsd/makefiles/mapfile-vers-jsig
+--- openjdk.orig/hotspot/make/bsd/makefiles/mapfile-vers-jsig 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/mapfile-vers-jsig 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,40 @@
++#
++
++#
++# Copyright (c) 2005, 2008, 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.
++#
++#
++
++# Define library interface.
++
++SUNWprivate_1.1 {
++ global:
++ JVM_begin_signal_setting;
++ JVM_end_signal_setting;
++ JVM_get_libjsig_version;
++ JVM_get_signal_action;
++ sigaction;
++ signal;
++ sigset;
++ local:
++ *;
++};
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/mapfile-vers-product openjdk/hotspot/make/bsd/makefiles/mapfile-vers-product
+--- openjdk.orig/hotspot/make/bsd/makefiles/mapfile-vers-product 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/mapfile-vers-product 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,286 @@
++#
++# @(#)mapfile-vers-product 1.19 08/02/12 10:56:37
++#
++
++#
++# Copyright (c) 2002, 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.
++#
++#
++
++# Define public interface.
++
++SUNWprivate_1.1 {
++ global:
++ # JNI
++ JNI_CreateJavaVM;
++ JNI_GetCreatedJavaVMs;
++ JNI_GetDefaultJavaVMInitArgs;
++
++ # JVM
++ JVM_Accept;
++ JVM_ActiveProcessorCount;
++ JVM_AllocateNewArray;
++ JVM_AllocateNewObject;
++ JVM_ArrayCopy;
++ JVM_AssertionStatusDirectives;
++ JVM_Available;
++ JVM_Bind;
++ JVM_ClassDepth;
++ JVM_ClassLoaderDepth;
++ JVM_Clone;
++ JVM_Close;
++ JVM_CX8Field;
++ JVM_CompileClass;
++ JVM_CompileClasses;
++ JVM_CompilerCommand;
++ JVM_Connect;
++ JVM_ConstantPoolGetClassAt;
++ JVM_ConstantPoolGetClassAtIfLoaded;
++ JVM_ConstantPoolGetDoubleAt;
++ JVM_ConstantPoolGetFieldAt;
++ JVM_ConstantPoolGetFieldAtIfLoaded;
++ JVM_ConstantPoolGetFloatAt;
++ JVM_ConstantPoolGetIntAt;
++ JVM_ConstantPoolGetLongAt;
++ JVM_ConstantPoolGetMethodAt;
++ JVM_ConstantPoolGetMethodAtIfLoaded;
++ JVM_ConstantPoolGetMemberRefInfoAt;
++ JVM_ConstantPoolGetSize;
++ JVM_ConstantPoolGetStringAt;
++ JVM_ConstantPoolGetUTF8At;
++ JVM_CountStackFrames;
++ JVM_CurrentClassLoader;
++ JVM_CurrentLoadedClass;
++ JVM_CurrentThread;
++ JVM_CurrentTimeMillis;
++ JVM_DefineClass;
++ JVM_DefineClassWithSource;
++ JVM_DefineClassWithSourceCond;
++ JVM_DesiredAssertionStatus;
++ JVM_DisableCompiler;
++ JVM_DoPrivileged;
++ JVM_DTraceGetVersion;
++ JVM_DTraceActivate;
++ JVM_DTraceIsProbeEnabled;
++ JVM_DTraceIsSupported;
++ JVM_DTraceDispose;
++ JVM_DumpAllStacks;
++ JVM_DumpThreads;
++ JVM_EnableCompiler;
++ JVM_Exit;
++ JVM_FillInStackTrace;
++ JVM_FindClassFromClass;
++ JVM_FindClassFromClassLoader;
++ JVM_FindClassFromBootLoader;
++ JVM_FindLibraryEntry;
++ JVM_FindLoadedClass;
++ JVM_FindPrimitiveClass;
++ JVM_FindSignal;
++ JVM_FreeMemory;
++ JVM_GC;
++ JVM_GetAllThreads;
++ JVM_GetArrayElement;
++ JVM_GetArrayLength;
++ JVM_GetCPClassNameUTF;
++ JVM_GetCPFieldClassNameUTF;
++ JVM_GetCPFieldModifiers;
++ JVM_GetCPFieldNameUTF;
++ JVM_GetCPFieldSignatureUTF;
++ JVM_GetCPMethodClassNameUTF;
++ JVM_GetCPMethodModifiers;
++ JVM_GetCPMethodNameUTF;
++ JVM_GetCPMethodSignatureUTF;
++ JVM_GetCallerClass;
++ JVM_GetClassAccessFlags;
++ JVM_GetClassAnnotations;
++ JVM_GetClassCPEntriesCount;
++ JVM_GetClassCPTypes;
++ JVM_GetClassConstantPool;
++ JVM_GetClassContext;
++ JVM_GetClassDeclaredConstructors;
++ JVM_GetClassDeclaredFields;
++ JVM_GetClassDeclaredMethods;
++ JVM_GetClassFieldsCount;
++ JVM_GetClassInterfaces;
++ JVM_GetClassLoader;
++ JVM_GetClassMethodsCount;
++ JVM_GetClassModifiers;
++ JVM_GetClassName;
++ JVM_GetClassNameUTF;
++ JVM_GetClassSignature;
++ JVM_GetClassSigners;
++ JVM_GetComponentType;
++ JVM_GetDeclaredClasses;
++ JVM_GetDeclaringClass;
++ JVM_GetEnclosingMethodInfo;
++ JVM_GetFieldAnnotations;
++ JVM_GetFieldIxModifiers;
++ JVM_GetHostName;
++ JVM_GetInheritedAccessControlContext;
++ JVM_GetInterfaceVersion;
++ JVM_GetLastErrorString;
++ JVM_GetManagement;
++ JVM_GetMethodAnnotations;
++ JVM_GetMethodDefaultAnnotationValue;
++ JVM_GetMethodIxArgsSize;
++ JVM_GetMethodIxByteCode;
++ JVM_GetMethodIxByteCodeLength;
++ JVM_GetMethodIxExceptionIndexes;
++ JVM_GetMethodIxExceptionTableEntry;
++ JVM_GetMethodIxExceptionTableLength;
++ JVM_GetMethodIxExceptionsCount;
++ JVM_GetMethodIxLocalsCount;
++ JVM_GetMethodIxMaxStack;
++ JVM_GetMethodIxModifiers;
++ JVM_GetMethodIxNameUTF;
++ JVM_GetMethodIxSignatureUTF;
++ JVM_GetMethodParameterAnnotations;
++ JVM_GetPrimitiveArrayElement;
++ JVM_GetProtectionDomain;
++ JVM_GetSockName;
++ JVM_GetSockOpt;
++ JVM_GetStackAccessControlContext;
++ JVM_GetStackTraceDepth;
++ JVM_GetStackTraceElement;
++ JVM_GetSystemPackage;
++ JVM_GetSystemPackages;
++ JVM_GetThreadStateNames;
++ JVM_GetThreadStateValues;
++ JVM_GetVersionInfo;
++ JVM_Halt;
++ JVM_HoldsLock;
++ JVM_IHashCode;
++ JVM_InitAgentProperties;
++ JVM_InitProperties;
++ JVM_InitializeCompiler;
++ JVM_InitializeSocketLibrary;
++ JVM_InternString;
++ JVM_Interrupt;
++ JVM_InvokeMethod;
++ JVM_IsArrayClass;
++ JVM_IsConstructorIx;
++ JVM_IsInterface;
++ JVM_IsInterrupted;
++ JVM_IsNaN;
++ JVM_IsPrimitiveClass;
++ JVM_IsSameClassPackage;
++ JVM_IsSilentCompiler;
++ JVM_IsSupportedJNIVersion;
++ JVM_IsThreadAlive;
++ JVM_LatestUserDefinedLoader;
++ JVM_Listen;
++ JVM_LoadClass0;
++ JVM_LoadLibrary;
++ JVM_Lseek;
++ JVM_MaxObjectInspectionAge;
++ JVM_MaxMemory;
++ JVM_MonitorNotify;
++ JVM_MonitorNotifyAll;
++ JVM_MonitorWait;
++ JVM_NanoTime;
++ JVM_NativePath;
++ JVM_NewArray;
++ JVM_NewInstanceFromConstructor;
++ JVM_NewMultiArray;
++ JVM_OnExit;
++ JVM_Open;
++ JVM_PrintStackTrace;
++ JVM_RaiseSignal;
++ JVM_RawMonitorCreate;
++ JVM_RawMonitorDestroy;
++ JVM_RawMonitorEnter;
++ JVM_RawMonitorExit;
++ JVM_Read;
++ JVM_Recv;
++ JVM_RecvFrom;
++ JVM_RegisterSignal;
++ JVM_ReleaseUTF;
++ JVM_ResolveClass;
++ JVM_ResumeThread;
++ JVM_Send;
++ JVM_SendTo;
++ JVM_SetArrayElement;
++ JVM_SetClassSigners;
++ JVM_SetLength;
++ JVM_SetPrimitiveArrayElement;
++ JVM_SetProtectionDomain;
++ JVM_SetSockOpt;
++ JVM_SetThreadPriority;
++ JVM_Sleep;
++ JVM_Socket;
++ JVM_SocketAvailable;
++ JVM_SocketClose;
++ JVM_SocketShutdown;
++ JVM_StartThread;
++ JVM_StopThread;
++ JVM_SuspendThread;
++ JVM_SupportsCX8;
++ JVM_Sync;
++ JVM_Timeout;
++ JVM_TotalMemory;
++ JVM_TraceInstructions;
++ JVM_TraceMethodCalls;
++ JVM_UnloadLibrary;
++ JVM_Write;
++ JVM_Yield;
++ JVM_handle_bsd_signal;
++
++ # Old reflection routines
++ # These do not need to be present in the product build in JDK 1.4
++ # but their code has not been removed yet because there will not
++ # be a substantial code savings until JVM_InvokeMethod and
++ # JVM_NewInstanceFromConstructor can also be removed; see
++ # reflectionCompat.hpp.
++ JVM_GetClassConstructor;
++ JVM_GetClassConstructors;
++ JVM_GetClassField;
++ JVM_GetClassFields;
++ JVM_GetClassMethod;
++ JVM_GetClassMethods;
++ JVM_GetField;
++ JVM_GetPrimitiveField;
++ JVM_NewInstance;
++ JVM_SetField;
++ JVM_SetPrimitiveField;
++
++ # miscellaneous functions
++ jio_fprintf;
++ jio_printf;
++ jio_snprintf;
++ jio_vfprintf;
++ jio_vsnprintf;
++ fork1;
++ numa_warn;
++ numa_error;
++
++ # Needed because there is no JVM interface for this.
++ sysThreadAvailableStackWithSlack;
++
++ # This is for Forte Analyzer profiling support.
++ AsyncGetCallTrace;
++
++ # INSERT VTABLE SYMBOLS HERE
++
++ local:
++ *;
++};
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/optimized.make openjdk/hotspot/make/bsd/makefiles/optimized.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/optimized.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/optimized.make 2013-04-08 01:49:33.586321555 +0100
+@@ -0,0 +1,44 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making optimized version of Gamma VM
++# (This is the "product", not the "release" version.)
++
++# Compiler specific OPT_CFLAGS are passed in from gcc.make, sparcWorks.make
++OPT_CFLAGS/DEFAULT= $(OPT_CFLAGS)
++OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
++
++# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
++
++# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
++CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
++
++# Set the environment variable HOTSPARC_GENERIC to "true"
++# to inhibit the effect of the previous line on CFLAGS.
++
++# Linker mapfile
++MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
++
++G_SUFFIX =
++VERSION = optimized
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/ppc.make openjdk/hotspot/make/bsd/makefiles/ppc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/ppc.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/ppc.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,30 @@
++#
++# Copyright (c) 2004, 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.
++#
++#
++
++# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
++
++# Must also specify if CPU is big endian
++CFLAGS += -DVM_BIG_ENDIAN
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/product.make openjdk/hotspot/make/bsd/makefiles/product.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/product.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/product.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,58 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++# Sets make macros for making optimized version of Gamma VM
++# (This is the "product", not the "release" version.)
++
++# Compiler specific OPT_CFLAGS are passed in from gcc.make, sparcWorks.make
++OPT_CFLAGS/DEFAULT= $(OPT_CFLAGS)
++OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
++
++# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
++
++# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings
++CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
++
++# Set the environment variable HOTSPARC_GENERIC to "true"
++# to inhibit the effect of the previous line on CFLAGS.
++
++# Linker mapfile
++MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-product
++
++G_SUFFIX =
++SYSDEFS += -DPRODUCT
++VERSION = optimized
++
++# use -g to strip library as -x will discard its symbol table; -x is fine for
++# executables.
++ifdef CROSS_COMPILE_ARCH
++ STRIP = $(ALT_COMPILER_PATH)/strip
++else
++ STRIP = strip
++endif
++STRIP_LIBJVM = $(STRIP) -g $@ || exit 1;
++STRIP_AOUT = $(STRIP) -x $@ || exit 1;
++
++# Don't strip in VM build; JDK build will strip libraries later
++# LINK_LIB.CC/POST_HOOK += $(STRIP_$(LINK_INTO))
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/profiled.make openjdk/hotspot/make/bsd/makefiles/profiled.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/profiled.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/profiled.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,30 @@
++#
++# Copyright (c) 1999, 2008, 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.
++#
++#
++
++# Sets make macros for making profiled version of Gamma VM
++# (It is also optimized.)
++
++CFLAGS += -pg
++AOUT_FLAGS += -pg
++LDNOMAP = true
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/rules.make openjdk/hotspot/make/bsd/makefiles/rules.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/rules.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/rules.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,216 @@
++#
++# 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.
++#
++#
++
++# Common rules/macros for the vm, adlc.
++
++# Tell make that .cpp is important
++.SUFFIXES: .cpp $(SUFFIXES)
++
++# For now. Other makefiles use CPP as the c++ compiler, but that should really
++# name the preprocessor.
++ifeq ($(CCC),)
++CCC = $(CPP)
++endif
++
++DEMANGLER = c++filt
++DEMANGLE = $(DEMANGLER) < $@ > .$@ && mv -f .$@ $@
++
++# $(CC) is the c compiler (cc/gcc), $(CCC) is the c++ compiler (CC/g++).
++C_COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS)
++CC_COMPILE = $(CCC) $(CPPFLAGS) $(CFLAGS)
++
++AS.S = $(AS) $(ASFLAGS)
++
++COMPILE.c = $(C_COMPILE) -c
++GENASM.c = $(C_COMPILE) -S
++LINK.c = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS)
++LINK_LIB.c = $(CC) $(LFLAGS) $(SHARED_FLAG)
++PREPROCESS.c = $(C_COMPILE) -E
++
++COMPILE.CC = $(CC_COMPILE) -c
++GENASM.CC = $(CC_COMPILE) -S
++LINK.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS)
++LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS)
++LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG)
++PREPROCESS.CC = $(CC_COMPILE) -E
++
++# cross compiling the jvm with c2 requires host compilers to build
++# adlc tool
++
++HOST.CC_COMPILE = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS)
++HOST.COMPILE.CC = $(HOST.CC_COMPILE) -c
++HOST.LINK_NOPROF.CC = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS)
++
++
++# Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k".
++REMOVE_TARGET = rm -f $@
++
++# Synonyms.
++COMPILE.cpp = $(COMPILE.CC)
++GENASM.cpp = $(GENASM.CC)
++LINK.cpp = $(LINK.CC)
++LINK_LIB.cpp = $(LINK_LIB.CC)
++PREPROCESS.cpp = $(PREPROCESS.CC)
++
++# Note use of ALT_BOOTDIR to explicitly specify location of java and
++# javac; this is the same environment variable used in the J2SE build
++# process for overriding the default spec, which is BOOTDIR.
++# Note also that we fall back to using JAVA_HOME if neither of these is
++# specified.
++
++ifdef ALT_BOOTDIR
++
++RUN.JAVA = $(ALT_BOOTDIR)/bin/java
++RUN.JAVAP = $(ALT_BOOTDIR)/bin/javap
++RUN.JAVAH = $(ALT_BOOTDIR)/bin/javah
++RUN.JAR = $(ALT_BOOTDIR)/bin/jar
++COMPILE.JAVAC = $(ALT_BOOTDIR)/bin/javac
++COMPILE.RMIC = $(ALT_BOOTDIR)/bin/rmic
++BOOT_JAVA_HOME = $(ALT_BOOTDIR)
++
++else
++
++ifdef BOOTDIR
++
++RUN.JAVA = $(BOOTDIR)/bin/java
++RUN.JAVAP = $(BOOTDIR)/bin/javap
++RUN.JAVAH = $(BOOTDIR)/bin/javah
++RUN.JAR = $(BOOTDIR)/bin/jar
++COMPILE.JAVAC = $(BOOTDIR)/bin/javac
++COMPILE.RMIC = $(BOOTDIR)/bin/rmic
++BOOT_JAVA_HOME = $(BOOTDIR)
++
++else
++
++ifdef JAVA_HOME
++
++RUN.JAVA = $(JAVA_HOME)/bin/java
++RUN.JAVAP = $(JAVA_HOME)/bin/javap
++RUN.JAVAH = $(JAVA_HOME)/bin/javah
++RUN.JAR = $(JAVA_HOME)/bin/jar
++COMPILE.JAVAC = $(JAVA_HOME)/bin/javac
++COMPILE.RMIC = $(JAVA_HOME)/bin/rmic
++BOOT_JAVA_HOME = $(JAVA_HOME)
++
++else
++
++# take from the PATH, if ALT_BOOTDIR, BOOTDIR and JAVA_HOME are not defined
++# note that this is to support hotspot build without SA. To build
++# SA along with hotspot, you need to define ALT_BOOTDIR, BOOTDIR or JAVA_HOME
++
++RUN.JAVA = java
++RUN.JAVAP = javap
++RUN.JAVAH = javah
++RUN.JAR = jar
++COMPILE.JAVAC = javac
++COMPILE.RMIC = rmic
++
++endif
++endif
++endif
++
++COMPILE.JAVAC += $(BOOTSTRAP_JAVAC_FLAGS)
++
++SUM = /usr/bin/sum
++
++# 'gmake MAKE_VERBOSE=y' gives all the gory details.
++QUIETLY$(MAKE_VERBOSE) = @
++RUN.JAR$(MAKE_VERBOSE) += >/dev/null
++
++# Settings for javac
++BOOT_SOURCE_LANGUAGE_VERSION = 6
++BOOT_TARGET_CLASS_VERSION = 6
++JAVAC_FLAGS = -g -encoding ascii
++BOOTSTRAP_JAVAC_FLAGS = $(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
++
++# With parallel makes, print a message at the end of compilation.
++ifeq ($(findstring j,$(MFLAGS)),j)
++COMPILE_DONE = && { echo Done with $<; }
++endif
++
++# Include $(NONPIC_OBJ_FILES) definition
++ifndef LP64
++include $(GAMMADIR)/make/pic.make
++endif
++
++include $(GAMMADIR)/make/altsrc.make
++
++# The non-PIC object files are only generated for 32 bit platforms.
++ifdef LP64
++%.o: %.cpp
++ @echo Compiling $<
++ $(QUIETLY) $(REMOVE_TARGET)
++ $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)
++else
++%.o: %.cpp
++ @echo Compiling $<
++ $(QUIETLY) $(REMOVE_TARGET)
++ $(QUIETLY) $(if $(findstring $@, $(NONPIC_OBJ_FILES)), \
++ $(subst $(VM_PICFLAG), ,$(COMPILE.CC)) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE), \
++ $(COMPILE.CC) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE))
++endif
++
++%.o: %.s
++ @echo Assembling $<
++ $(QUIETLY) $(REMOVE_TARGET)
++ $(QUIETLY) $(AS.S) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)
++
++%.s: %.cpp
++ @echo Generating assembly for $<
++ $(QUIETLY) $(GENASM.CC) -o $@ $<
++ $(QUIETLY) $(DEMANGLE) $(COMPILE_DONE)
++
++# Intermediate files (for debugging macros)
++%.i: %.cpp
++ @echo Preprocessing $< to $@
++ $(QUIETLY) $(PREPROCESS.CC) $< > $@ $(COMPILE_DONE)
++
++# Override gnumake built-in rules which do sccs get operations badly.
++# (They put the checked out code in the current directory, not in the
++# directory of the original file.) Since this is a symptom of a teamware
++# failure, and since not all problems can be detected by gnumake due
++# to incomplete dependency checking... just complain and stop.
++%:: s.%
++ @echo "========================================================="
++ @echo File $@
++ @echo is out of date with respect to its SCCS file.
++ @echo This file may be from an unresolved Teamware conflict.
++ @echo This is also a symptom of a Teamware bringover/putback failure
++ @echo in which SCCS files are updated but not checked out.
++ @echo Check for other out of date files in your workspace.
++ @echo "========================================================="
++ @exit 666
++
++%:: SCCS/s.%
++ @echo "========================================================="
++ @echo File $@
++ @echo is out of date with respect to its SCCS file.
++ @echo This file may be from an unresolved Teamware conflict.
++ @echo This is also a symptom of a Teamware bringover/putback failure
++ @echo in which SCCS files are updated but not checked out.
++ @echo Check for other out of date files in your workspace.
++ @echo "========================================================="
++ @exit 666
++
++.PHONY: default
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/sa.make openjdk/hotspot/make/bsd/makefiles/sa.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/sa.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/sa.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,121 @@
++#
++# 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 makefile (sa.make) is included from the sa.make in the
++# build directories.
++
++# This makefile is used to build Serviceability Agent java code
++# and generate JNI header file for native methods.
++
++include $(GAMMADIR)/make/bsd/makefiles/rules.make
++
++AGENT_DIR = $(GAMMADIR)/agent
++
++include $(GAMMADIR)/make/sa.files
++
++TOPDIR = $(shell echo `pwd`)
++GENERATED = $(TOPDIR)/../generated
++
++# tools.jar is needed by the JDI - SA binding
++SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar
++
++# 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
++
++SA_CLASSDIR = $(GENERATED)/saclasses
++
++SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)"
++
++SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
++
++# if $(AGENT_DIR) does not exist, we don't build SA
++# also, we don't build SA on Itanium, PowerPC, ARM or zero.
++
++all:
++ if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" \
++ -a "$(SRCARCH)" != "arm" \
++ -a "$(SRCARCH)" != "ppc" \
++ -a "$(SRCARCH)" != "zero" ] ; then \
++ $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
++ fi
++
++$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
++ $(QUIETLY) echo "Making $@"
++ $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
++ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
++ exit 1; \
++ fi
++ $(QUIETLY) if [ ! -f $(SA_CLASSPATH) -a ! -d $(MODULELIB_PATH) ] ; then \
++ echo "Missing $(SA_CLASSPATH) file. Use 1.6.0 or later version of JDK";\
++ echo ""; \
++ exit 1; \
++ fi
++ $(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
++# a very long cmd line, we use javac's @file-list option. We
++# generate the file lists using make's built-in 'foreach' control
++# flow which also avoids cmd processor line length issues. Since
++# the 'foreach' is done as part of make's macro expansion phase,
++# 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)
++
++ $(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
++ $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql
++ $(QUIETLY) mkdir -p $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
++ $(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/*
++ $(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources/
++ $(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)/
++ $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(SA_CLASSDIR)/ .
++ $(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
++ $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
++ $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext
++ $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
++ $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
++
++clean:
++ rm -rf $(SA_CLASSDIR)
++ rm -rf $(GENERATED)/sa-jdi.jar
++ rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/saproc.make openjdk/hotspot/make/bsd/makefiles/saproc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/saproc.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/saproc.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,107 @@
++#
++# 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.
++#
++#
++
++# Rules to build serviceability agent library, used by vm.make
++
++# libsaproc[_g].so: serviceability agent
++SAPROC = saproc
++SAPROC_G = $(SAPROC)$(G_SUFFIX)
++
++ifeq ($(OS_VENDOR), Darwin)
++ LIBSAPROC = lib$(SAPROC).dylib
++ LIBSAPROC_G = lib$(SAPROC_G).dylib
++else
++ LIBSAPROC = lib$(SAPROC).so
++ LIBSAPROC_G = lib$(SAPROC_G).so
++endif
++
++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
++
++SAMAPFILE = $(SASRCDIR)/mapfile
++
++DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC)
++
++# DEBUG_BINARIES overrides everything, use full -g debug information
++ifeq ($(DEBUG_BINARIES), true)
++ SA_DEBUG_CFLAGS = -g
++endif
++
++# if $(AGENT_DIR) does not exist, we don't build SA
++# also, we don't build SA on Itanium, PPC, ARM or zero.
++
++ifneq ($(wildcard $(AGENT_DIR)),)
++ifneq ($(filter-out ia64 arm ppc zero,$(SRCARCH)),)
++ BUILDLIBSAPROC = $(LIBSAPROC)
++endif
++endif
++
++
++ifneq ($(OS_VENDOR), Darwin)
++SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE))
++endif
++SA_LFLAGS += $(LDFLAGS_HASH_STYLE)
++
++$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
++ $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
++ echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
++ exit 1; \
++ fi
++ @echo Making SA debugger back-end...
++ $(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \
++ $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
++ -I$(SASRCDIR) \
++ -I$(GENERATED) \
++ -I$(BOOT_JAVA_HOME)/include \
++ -I$(BOOT_JAVA_HOME)/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") \
++ $(SASRCFILES) \
++ $(SA_LFLAGS) \
++ $(SA_DEBUG_CFLAGS) \
++ -o $@ \
++ $(SALIBS)
++ $(QUIETLY) [ -f $(LIBSAPROC_G) ] || { ln -s $@ $(LIBSAPROC_G); }
++
++install_saproc: $(BUILDLIBSAPROC)
++ $(QUIETLY) if [ -e $(LIBSAPROC) ] ; then \
++ echo "Copying $(LIBSAPROC) to $(DEST_SAPROC)"; \
++ cp -f $(LIBSAPROC) $(DEST_SAPROC) && echo "Done"; \
++ fi
++
++.PHONY: install_saproc
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/shark.make openjdk/hotspot/make/bsd/makefiles/shark.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/shark.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/shark.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,32 @@
++#
++# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
++# Copyright 2008, 2010 Red Hat, Inc.
++# 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.
++#
++#
++
++# Sets make macros for making Shark version of VM
++
++TYPE = SHARK
++
++VM_SUBDIR = server
++
++CFLAGS += -DSHARK
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/sparc.make openjdk/hotspot/make/bsd/makefiles/sparc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/sparc.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/sparc.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,24 @@
++#
++# 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.
++#
++#
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/sparcv9.make openjdk/hotspot/make/bsd/makefiles/sparcv9.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/sparcv9.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/sparcv9.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,27 @@
++#
++# 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.
++#
++
++# gcc 4.0 miscompiles this code in -m64
++OPT_CFLAGS/macro.o = -O0
++
++CFLAGS += -D_LP64=1
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/sparcWorks.make openjdk/hotspot/make/bsd/makefiles/sparcWorks.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/sparcWorks.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/sparcWorks.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,104 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++#------------------------------------------------------------------------
++# CC, CPP & AS
++
++CPP = CC
++CC = cc
++AS = $(CC) -c
++
++HOSTCPP = $(CPP)
++HOSTCC = $(CC)
++
++ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
++ARCHFLAG/i486 = -m32
++ARCHFLAG/amd64 = -m64
++
++CFLAGS += $(ARCHFLAG)
++AOUT_FLAGS += $(ARCHFLAG)
++LFLAGS += $(ARCHFLAG)
++ASFLAGS += $(ARCHFLAG)
++
++#------------------------------------------------------------------------
++# Compiler flags
++
++# position-independent code
++PICFLAG = -KPIC
++
++CFLAGS += $(PICFLAG)
++# no more exceptions
++CFLAGS += -features=no%except
++# Reduce code bloat by reverting back to 5.0 behavior for static initializers
++CFLAGS += -features=no%split_init
++# allow zero sized arrays
++CFLAGS += -features=zla
++
++# Use C++ Interpreter
++ifdef CC_INTERP
++ CFLAGS += -DCC_INTERP
++endif
++
++# We don't need libCstd.so and librwtools7.so, only libCrun.so
++CFLAGS += -library=Crun
++LIBS += -lCrun
++
++CFLAGS += -mt
++LFLAGS += -mt
++
++# Compiler warnings are treated as errors
++#WARNINGS_ARE_ERRORS = -errwarn=%all
++CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS)
++# Special cases
++CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
++
++# The flags to use for an Optimized build
++OPT_CFLAGS+=-xO4
++OPT_CFLAGS/NOOPT=-xO0
++
++# Flags for creating the dependency files.
++ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
++DEPFLAGS = -xMMD -xMF $(DEP_DIR)/$(@:%=%.d)
++endif
++
++# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
++CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
++
++#------------------------------------------------------------------------
++# Linker flags
++
++# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
++MAPFLAG = -Wl,--version-script=FILENAME
++
++# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
++SONAMEFLAG = -h SONAME
++
++# Build shared library
++SHARED_FLAG = -G
++
++#------------------------------------------------------------------------
++# Debug flags
++DEBUG_CFLAGS += -g
++FASTDEBUG_CFLAGS = -g0
++
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/tiered.make openjdk/hotspot/make/bsd/makefiles/tiered.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/tiered.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/tiered.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,31 @@
++#
++# Copyright (c) 2006, 2008, 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.
++#
++#
++
++# Sets make macros for making tiered version of VM
++
++TYPE=TIERED
++
++VM_SUBDIR = server
++
++CFLAGS += -DCOMPILER2 -DCOMPILER1
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/top.make openjdk/hotspot/make/bsd/makefiles/top.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/top.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/top.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,142 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++# top.make is included in the Makefile in the build directories.
++# It DOES NOT include the vm dependency info in order to be faster.
++# Its main job is to implement the incremental form of make lists.
++# It also:
++# -builds and runs adlc via adlc.make
++# -generates JVMTI source and docs via jvmti.make (JSR-163)
++# -generate sa-jdi.jar (JDI binding to core files)
++
++# It assumes the following flags are set:
++# CFLAGS Platform_file, Src_Dirs_I, Src_Dirs_V, SYSDEFS, AOUT, Obj_Files
++
++# -- D. Ungar (5/97) from a file by Bill Bush
++
++# Don't override the built-in $(MAKE).
++# Instead, use "gmake" (or "gnumake") from the command line. --Rose
++#MAKE = gmake
++
++include $(GAMMADIR)/make/altsrc.make
++
++TOPDIR = $(shell echo `pwd`)
++GENERATED = $(TOPDIR)/../generated
++VM = $(GAMMADIR)/src/share/vm
++Plat_File = $(Platform_file)
++CDG = cd $(GENERATED);
++
++ifdef USE_PRECOMPILED_HEADER
++PrecompiledOption = -DUSE_PRECOMPILED_HEADER
++UpdatePCH = $(MAKE) -f vm.make $(PRECOMPILED_HEADER) $(MFLAGS)
++else
++UpdatePCH = \# precompiled header is not used
++PrecompiledOption =
++endif
++
++Cached_plat = $(GENERATED)/platform.current
++
++AD_Dir = $(GENERATED)/adfiles
++ADLC = $(AD_Dir)/adlc
++AD_Spec = $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad)
++AD_Src = $(call altsrc-replace,$(HS_COMMON_SRC)/share/vm/adlc)
++AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
++AD_Files = $(AD_Names:%=$(AD_Dir)/%)
++
++# AD_Files_If_Required/COMPILER1 = ad_stuff
++AD_Files_If_Required/COMPILER2 = ad_stuff
++AD_Files_If_Required/TIERED = ad_stuff
++AD_Files_If_Required = $(AD_Files_If_Required/$(TYPE))
++
++# Wierd argument adjustment for "gnumake -j..."
++adjust-mflags = $(GENERATED)/adjust-mflags
++MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
++
++
++# default target: update lists, make vm
++# done in stages to force sequential order with parallel make
++#
++
++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
++ @# We need a null action here, so implicit rules don't get consulted.
++
++$(Cached_plat): $(Plat_File)
++ $(CDG) cp $(Plat_File) $(Cached_plat)
++
++# make AD files as necessary
++ad_stuff: $(Cached_plat) $(adjust-mflags)
++ @$(MAKE) -f adlc.make $(MFLAGS-adjusted)
++
++# generate JVMTI files from the spec
++jvmti_stuff: $(Cached_plat) $(adjust-mflags)
++ @$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
++
++# generate SA jar files and native header
++sa_stuff:
++ @$(MAKE) -f sa.make $(MFLAGS-adjusted)
++
++# and the VM: must use other makefile with dependencies included
++
++# We have to go to great lengths to get control over the -jN argument
++# to the recursive invocation of vm.make. The problem is that gnumake
++# resets -jN to -j1 for recursive runs. (How helpful.)
++# Note that the user must specify the desired parallelism level via a
++# command-line or environment variable name HOTSPOT_BUILD_JOBS.
++$(adjust-mflags): $(GAMMADIR)/make/$(Platform_os_family)/makefiles/adjust-mflags.sh
++ @+rm -f $@ $@+
++ @+cat $< > $@+
++ @+chmod +x $@+
++ @+mv $@+ $@
++
++the_vm: vm_build_preliminaries $(adjust-mflags)
++ @$(UpdatePCH)
++ @$(MAKE) -f vm.make $(MFLAGS-adjusted)
++
++install: the_vm
++ @$(MAKE) -f vm.make install
++
++# next rules support "make foo.[ois]"
++
++%.o %.i %.s:
++ $(UpdatePCH)
++ $(MAKE) -f vm.make $(MFLAGS) $@
++ #$(MAKE) -f vm.make $@
++
++# this should force everything to be rebuilt
++clean:
++ rm -f $(GENERATED)/*.class
++ $(MAKE) -f vm.make $(MFLAGS) clean
++
++# just in case it doesn't, this should do it
++realclean:
++ $(MAKE) -f vm.make $(MFLAGS) clean
++ rm -fr $(GENERATED)
++
++.PHONY: default vm_build_preliminaries
++.PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
++.PHONY: checks check_os_version install
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/vm.make openjdk/hotspot/make/bsd/makefiles/vm.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/vm.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/vm.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,329 @@
++#
++# Copyright (c) 1999, 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.
++#
++#
++
++# Rules to build JVM and related libraries, included from vm.make in the build
++# directory.
++
++# Common build rules.
++MAKEFILES_DIR=$(GAMMADIR)/make/$(Platform_os_family)/makefiles
++include $(MAKEFILES_DIR)/rules.make
++include $(GAMMADIR)/make/altsrc.make
++
++default: build
++
++#----------------------------------------------------------------------
++# Defs
++
++GENERATED = ../generated
++DEP_DIR = $(GENERATED)/dependencies
++
++# reads the generated files defining the set of .o's and the .o .h dependencies
++-include $(DEP_DIR)/*.d
++
++# read machine-specific adjustments (%%% should do this via buildtree.make?)
++ifeq ($(ZERO_BUILD), true)
++ include $(MAKEFILES_DIR)/zeroshark.make
++else
++ include $(MAKEFILES_DIR)/$(BUILDARCH).make
++endif
++
++# set VPATH so make knows where to look for source files
++# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
++# The adfiles directory contains ad_<arch>.[ch]pp.
++# The jvmtifiles directory contains jvmti*.[ch]pp
++Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
++VPATH += $(Src_Dirs_V:%=%:)
++
++# set INCLUDES for C preprocessor.
++Src_Dirs_I += $(GENERATED)
++# The order is important for the precompiled headers to work.
++INCLUDES += $(PRECOMPILED_HEADER_DIR:%=-I%) $(Src_Dirs_I:%=-I%)
++
++ifeq (${VERSION}, debug)
++ SYMFLAG = -g
++else
++ SYMFLAG =
++endif
++
++# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
++# in $(GAMMADIR)/make/defs.make
++ifeq ($(HOTSPOT_BUILD_VERSION),)
++ BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
++else
++ BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)\""
++endif
++
++# The following variables are defined in the generated flags.make file.
++BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HS_BUILD_VER)\""
++JRE_VERSION = -DJRE_RELEASE_VERSION="\"$(JRE_RELEASE_VER)\""
++HS_LIB_ARCH = -DHOTSPOT_LIB_ARCH=\"$(LIBARCH)\"
++BUILD_TARGET = -DHOTSPOT_BUILD_TARGET="\"$(TARGET)\""
++BUILD_USER = -DHOTSPOT_BUILD_USER="\"$(HOTSPOT_BUILD_USER)\""
++VM_DISTRO = -DHOTSPOT_VM_DISTRO="\"$(HOTSPOT_VM_DISTRO)\""
++
++CPPFLAGS = \
++ ${SYSDEFS} \
++ ${INCLUDES} \
++ ${BUILD_VERSION} \
++ ${BUILD_TARGET} \
++ ${BUILD_USER} \
++ ${HS_LIB_ARCH} \
++ ${JRE_VERSION} \
++ ${VM_DISTRO}
++
++ifdef DEFAULT_LIBPATH
++CPPFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
++endif
++
++# CFLAGS_WARN holds compiler options to suppress/enable warnings.
++CFLAGS += $(CFLAGS_WARN/BYFILE)
++
++# Do not use C++ exception handling
++CFLAGS += $(CFLAGS/NOEX)
++
++# Extra flags from gnumake's invocation or environment
++CFLAGS += $(EXTRA_CFLAGS)
++LFLAGS += $(EXTRA_CFLAGS)
++
++# Don't set excutable bit on stack segment
++# the same could be done by separate execstack command
++ifneq ($(OS_VENDOR), Darwin)
++LFLAGS += -Xlinker -z -Xlinker noexecstack
++endif
++
++LIBS += -lm -pthread
++
++# By default, link the *.o into the library, not the executable.
++LINK_INTO$(LINK_INTO) = LIBJVM
++
++JDK_LIBDIR = $(JAVA_HOME)/jre/lib/$(LIBARCH)
++
++#----------------------------------------------------------------------
++# jvm_db & dtrace
++include $(MAKEFILES_DIR)/dtrace.make
++
++#----------------------------------------------------------------------
++# JVM
++
++JVM = jvm
++ifeq ($(OS_VENDOR), Darwin)
++ LIBJVM = lib$(JVM).dylib
++ LIBJVM_G = lib$(JVM)$(G_SUFFIX).dylib
++ CFLAGS += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE
++else
++ LIBJVM = lib$(JVM).so
++ LIBJVM_G = lib$(JVM)$(G_SUFFIX).so
++endif
++
++SPECIAL_PATHS:=adlc c1 gc_implementation opto shark libadt
++
++SOURCE_PATHS=\
++ $(shell find $(HS_COMMON_SRC)/share/vm/* -type d \! \
++ \( -name DUMMY $(foreach dir,$(SPECIAL_PATHS),-o -name $(dir)) \))
++SOURCE_PATHS+=$(HS_COMMON_SRC)/os/$(Platform_os_family)/vm
++SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
++SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
++SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
++
++CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
++CORE_PATHS+=$(GENERATED)/jvmtifiles
++
++COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
++COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
++
++COMPILER2_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/opto)
++COMPILER2_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/libadt)
++COMPILER2_PATHS += $(HS_COMMON_SRC)/share/vm/opto
++COMPILER2_PATHS += $(HS_COMMON_SRC)/share/vm/libadt
++COMPILER2_PATHS += $(GENERATED)/adfiles
++
++SHARK_PATHS := $(GAMMADIR)/src/share/vm/shark
++
++# Include dirs per type.
++Src_Dirs/CORE := $(CORE_PATHS)
++Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS)
++Src_Dirs/COMPILER2 := $(CORE_PATHS) $(COMPILER2_PATHS)
++Src_Dirs/TIERED := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS)
++Src_Dirs/ZERO := $(CORE_PATHS)
++Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS)
++Src_Dirs := $(Src_Dirs/$(TYPE))
++
++COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
++COMPILER1_SPECIFIC_FILES := c1_\*
++SHARK_SPECIFIC_FILES := shark
++ZERO_SPECIFIC_FILES := zero
++
++# Always exclude these.
++Src_Files_EXCLUDE := jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp
++
++# Exclude per type.
++Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
++Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
++Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES)
++Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES)
++Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp
++Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES)
++
++Src_Files_EXCLUDE += $(Src_Files_EXCLUDE/$(TYPE))
++
++# Special handling of arch model.
++ifeq ($(Platform_arch_model), x86_32)
++Src_Files_EXCLUDE += \*x86_64\*
++endif
++ifeq ($(Platform_arch_model), x86_64)
++Src_Files_EXCLUDE += \*x86_32\*
++endif
++
++# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
++define findsrc
++ $(notdir $(shell find $(1)/. ! -name . -prune \
++ -a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
++ -a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
++endef
++
++Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
++
++Obj_Files = $(sort $(addsuffix .o,$(basename $(Src_Files))))
++
++JVM_OBJ_FILES = $(Obj_Files)
++
++vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))
++
++mapfile : $(MAPFILE) vm.def
++ rm -f $@
++ awk '{ if ($$0 ~ "INSERT VTABLE SYMBOLS HERE") \
++ { system ("cat vm.def"); } \
++ else \
++ { print $$0 } \
++ }' > $@ < $(MAPFILE)
++
++mapfile_reorder : mapfile $(REORDERFILE)
++ rm -f $@
++ cat $^ > $@
++
++vm.def: $(Res_Files) $(Obj_Files)
++ sh $(GAMMADIR)/make/bsd/makefiles/build_vm_def.sh *.o > $@
++
++STATIC_CXX = false
++
++ifeq ($(LINK_INTO),AOUT)
++ LIBJVM.o =
++ LIBJVM_MAPFILE =
++ LIBS_VM = $(LIBS)
++else
++ LIBJVM.o = $(JVM_OBJ_FILES)
++ LIBJVM_MAPFILE$(LDNOMAP) = mapfile_reorder
++ LFLAGS_VM$(LDNOMAP) += $(MAPFLAG:FILENAME=$(LIBJVM_MAPFILE))
++ LFLAGS_VM += $(SONAMEFLAG:SONAME=$(LIBJVM))
++
++ ifeq ($(OS_VENDOR), Darwin)
++ LFLAGS_VM += -Xlinker -rpath -Xlinker @loader_path/.
++ LFLAGS_VM += -Xlinker -rpath -Xlinker @loader_path/..
++ LFLAGS_VM += -Xlinker -install_name -Xlinker @rpath/$(@F)
++ endif
++
++ # JVM is statically linked with libgcc[_s] and libstdc++; this is needed to
++ # get around library dependency and compatibility issues. Must use gcc not
++ # g++ to link.
++ ifeq ($(STATIC_CXX), true)
++ LFLAGS_VM += $(STATIC_LIBGCC)
++ LIBS_VM += $(STATIC_STDCXX)
++ LINK_VM = $(LINK_LIB.c)
++ else
++ LINK_VM = $(LINK_LIB.CC)
++ endif
++
++ LIBS_VM += $(LIBS)
++endif
++ifeq ($(ZERO_BUILD), true)
++ LIBS_VM += $(LIBFFI_LIBS)
++endif
++ifeq ($(SHARK_BUILD), true)
++ LFLAGS_VM += $(LLVM_LDFLAGS)
++ LIBS_VM += $(LLVM_LIBS)
++endif
++
++
++# rule for building precompiled header
++$(PRECOMPILED_HEADER):
++ $(QUIETLY) echo Generating precompiled header $@
++ $(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR)
++ $(QUIETLY) $(COMPILE.CC) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE)
++
++# making the library:
++
++ifneq ($(JVM_BASE_ADDR),)
++# By default shared library is linked at base address == 0. Modify the
++# linker script if JVM prefers a different base location. It can also be
++# implemented with 'prelink -r'. But 'prelink' is not (yet) available on
++# our build platform (AS-2.1).
++LD_SCRIPT = libjvm.so.lds
++$(LD_SCRIPT): $(LIBJVM_MAPFILE)
++ $(QUIETLY) { \
++ rm -rf $@; \
++ $(LINK_VM) -Wl,--verbose $(LFLAGS_VM) 2>&1 | \
++ sed -e '/^======/,/^======/!d' \
++ -e '/^======/d' \
++ -e 's/0\( + SIZEOF_HEADERS\)/$(JVM_BASE_ADDR)\1/' \
++ > $@; \
++ }
++LD_SCRIPT_FLAG = -Wl,-T,$(LD_SCRIPT)
++endif
++
++$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
++ $(QUIETLY) { \
++ echo Linking vm...; \
++ $(LINK_LIB.CC/PRE_HOOK) \
++ $(LINK_VM) $(LD_SCRIPT_FLAG) \
++ $(LFLAGS_VM) -o $@ $(LIBJVM.o) $(LIBS_VM); \
++ $(LINK_LIB.CC/POST_HOOK) \
++ rm -f $@.1; ln -s $@ $@.1; \
++ [ -f $(LIBJVM_G) ] || { ln -s $@ $(LIBJVM_G); ln -s $@.1 $(LIBJVM_G).1; }; \
++ }
++
++DEST_JVM = $(JDK_LIBDIR)/$(VM_SUBDIR)/$(LIBJVM)
++
++install_jvm: $(LIBJVM)
++ @echo "Copying $(LIBJVM) to $(DEST_JVM)"
++ $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done"
++
++#----------------------------------------------------------------------
++# Other files
++
++# Gamma launcher
++include $(MAKEFILES_DIR)/launcher.make
++
++# Signal interposition library
++include $(MAKEFILES_DIR)/jsig.make
++
++# Serviceability agent
++include $(MAKEFILES_DIR)/saproc.make
++
++#----------------------------------------------------------------------
++
++build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
++
++install: install_jvm install_jsig install_saproc
++
++.PHONY: default build install install_jvm
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/zero.make openjdk/hotspot/make/bsd/makefiles/zero.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/zero.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/zero.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,32 @@
++#
++# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
++# Copyright 2009 Red Hat, Inc.
++# 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.
++#
++#
++
++# Setup for Zero (non-Shark) version of VM
++
++# Select which files to use (in top.make)
++TYPE = ZERO
++
++# Install libjvm.so, etc in in server directory.
++VM_SUBDIR = server
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/zeroshark.make openjdk/hotspot/make/bsd/makefiles/zeroshark.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/zeroshark.make 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/makefiles/zeroshark.make 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,62 @@
++#
++# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
++# Copyright 2007, 2008 Red Hat, Inc.
++# 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.
++#
++#
++
++# Setup common to Zero (non-Shark) and Shark versions of VM
++
++# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
++# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
++OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
++
++# Specify that the CPU is little endian, if necessary
++ifeq ($(ZERO_ENDIANNESS), little)
++ CFLAGS += -DVM_LITTLE_ENDIAN
++endif
++
++# Specify that the CPU is 64 bit, if necessary
++ifeq ($(ARCH_DATA_MODEL), 64)
++ CFLAGS += -D_LP64=1
++endif
++
++# Specify the path to the FFI headers
++ifdef ALT_PACKAGE_PATH
++ PACKAGE_PATH = $(ALT_PACKAGE_PATH)
++else
++ ifeq ($(OS_VENDOR),Apple)
++ PACKAGE_PATH = /opt/local
++ else
++ ifeq ($(OS_VENDOR),NetBSD)
++ PACKAGE_PATH = /usr/pkg
++ LIBS += -Wl,-R${PACKAGE_PATH}/lib
++ else
++ PACKAGE_PATH = /usr/local
++ endif
++ endif
++endif
++
++CFLAGS += -I$(PACKAGE_PATH)/include
++LIBS += -L$(PACKAGE_PATH)/lib -lffi
++
++OPT_CFLAGS/compactingPermGenGen.o = -O1
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_amd64 openjdk/hotspot/make/bsd/platform_amd64
+--- openjdk.orig/hotspot/make/bsd/platform_amd64 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_amd64 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,15 @@
++os_family = bsd
++
++arch = x86
++
++arch_model = x86_64
++
++os_arch = bsd_x86
++
++os_arch_model = bsd_x86_64
++
++lib_arch = amd64
++
++compiler = gcc
++
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DAMD64
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_amd64.suncc openjdk/hotspot/make/bsd/platform_amd64.suncc
+--- openjdk.orig/hotspot/make/bsd/platform_amd64.suncc 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_amd64.suncc 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,17 @@
++os_family = bsd
++
++arch = x86
++
++arch_model = x86_64
++
++os_arch = bsd_x86
++
++os_arch_model = bsd_x86_64
++
++lib_arch = amd64
++
++compiler = sparcWorks
++
++gnu_dis_arch = amd64
++
++sysdefs = -D_ALLBSD_SOURCE -DSPARC_WORKS -D_GNU_SOURCE -DAMD64
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_i486 openjdk/hotspot/make/bsd/platform_i486
+--- openjdk.orig/hotspot/make/bsd/platform_i486 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_i486 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,15 @@
++os_family = bsd
++
++arch = x86
++
++arch_model = x86_32
++
++os_arch = bsd_x86
++
++os_arch_model = bsd_x86_32
++
++lib_arch = i386
++
++compiler = gcc
++
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DIA32
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_i486.suncc openjdk/hotspot/make/bsd/platform_i486.suncc
+--- openjdk.orig/hotspot/make/bsd/platform_i486.suncc 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_i486.suncc 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,17 @@
++os_family = bsd
++
++arch = x86
++
++arch_model = x86_32
++
++os_arch = bsd_x86
++
++os_arch_model = bsd_x86_32
++
++lib_arch = i386
++
++compiler = sparcWorks
++
++gnu_dis_arch = i386
++
++sysdefs = -D_ALLBSD_SOURCE -DSPARC_WORKS -D_GNU_SOURCE -DIA32
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_ia64 openjdk/hotspot/make/bsd/platform_ia64
+--- openjdk.orig/hotspot/make/bsd/platform_ia64 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_ia64 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,15 @@
++os_family = bsd
++
++arch = ia64
++
++os_arch = bsd_ia64
++
++lib_arch = ia64
++
++compiler = gcc
++
++gnu_dis_arch = ia64
++
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DIA64 -DCC_INTERP
++
++mark_style = alignment
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_sparc openjdk/hotspot/make/bsd/platform_sparc
+--- openjdk.orig/hotspot/make/bsd/platform_sparc 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_sparc 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,15 @@
++os_family = bsd
++
++arch = sparc
++
++arch_model = sparc
++
++os_arch = bsd_sparc
++
++os_arch_model = bsd_sparc
++
++lib_arch = sparc
++
++compiler = gcc
++
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DSPARC
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_sparcv9 openjdk/hotspot/make/bsd/platform_sparcv9
+--- openjdk.orig/hotspot/make/bsd/platform_sparcv9 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_sparcv9 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,15 @@
++os_family = bsd
++
++arch = sparc
++
++arch_model = sparc
++
++os_arch = bsd_sparc
++
++os_arch_model = bsd_sparc
++
++lib_arch = sparcv9
++
++compiler = gcc
++
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DSPARC
+diff -Nru openjdk.orig/hotspot/make/bsd/platform_zero.in openjdk/hotspot/make/bsd/platform_zero.in
+--- openjdk.orig/hotspot/make/bsd/platform_zero.in 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/platform_zero.in 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,17 @@
++os_family = bsd
++
++arch = zero
++
++arch_model = zero
++
++os_arch = bsd_zero
++
++os_arch_model = bsd_zero
++
++lib_arch = zero
++
++compiler = gcc
++
++gnu_dis_arch = zero
++
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DCC_INTERP -DZERO -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\"
+diff -Nru openjdk.orig/hotspot/make/bsd/README openjdk/hotspot/make/bsd/README
+--- openjdk.orig/hotspot/make/bsd/README 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/make/bsd/README 2013-04-08 01:49:33.590321620 +0100
+@@ -0,0 +1,26 @@
++Copyright (c) 2007, 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.
++
++________________________________________________________________________
++
++Please refer to the comments in the Makefile in this directory
++for instructions how to build the Solaris versions.
++
+diff -Nru openjdk.orig/hotspot/make/cscope.make openjdk/hotspot/make/cscope.make
+--- openjdk.orig/hotspot/make/cscope.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/cscope.make 2013-04-08 01:49:33.590321620 +0100
+@@ -63,7 +63,7 @@
+ # space-separated list of identifiers to include only those systems.
+ ifdef CS_OS
+ CS_PRUNE_OS = $(patsubst %,-o -name '*%*',\
+- $(filter-out ${CS_OS},linux macos solaris windows))
++ $(filter-out ${CS_OS},bsd linux macos solaris windows))
+ endif
+
+ # CPU-specific files for all processors are included by default. Set CS_CPU
+diff -Nru openjdk.orig/hotspot/make/defs.make openjdk/hotspot/make/defs.make
+--- openjdk.orig/hotspot/make/defs.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/defs.make 2013-04-08 01:49:33.590321620 +0100
+@@ -118,13 +118,23 @@
+ # Windows should have OS predefined
+ ifeq ($(OS),)
+ OS := $(shell uname -s)
++ ifneq ($(findstring BSD,$(OS)),)
++ OS=bsd
++ endif
++ ifeq ($(OS), Darwin)
++ OS=bsd
++ endif
+ HOST := $(shell uname -n)
+ endif
+
+-# If not SunOS and not Linux, assume Windows
++# If not SunOS, not Linux and not BSD, assume Windows
+ ifneq ($(OS), Linux)
+ ifneq ($(OS), SunOS)
+- OSNAME=windows
++ ifneq ($(OS), bsd)
++ OSNAME=windows
++ else
++ OSNAME=bsd
++ endif
+ else
+ OSNAME=solaris
+ endif
+diff -Nru openjdk.orig/hotspot/make/linux/makefiles/arm.make openjdk/hotspot/make/linux/makefiles/arm.make
+--- openjdk.orig/hotspot/make/linux/makefiles/arm.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/linux/makefiles/arm.make 2013-04-08 01:49:33.590321620 +0100
+@@ -1,6 +1,25 @@
+ #
+ # Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+-# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
++# 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.
++#
+ #
+
+ Obj_Files += linux_arm.o
+diff -Nru openjdk.orig/hotspot/make/linux/makefiles/defs.make openjdk/hotspot/make/linux/makefiles/defs.make
+--- openjdk.orig/hotspot/make/linux/makefiles/defs.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/linux/makefiles/defs.make 2013-04-08 01:50:51.543574767 +0100
+@@ -177,13 +177,16 @@
+
+ JDK_INCLUDE_SUBDIR=linux
+
++# Library suffix
++LIBRARY_SUFFIX=so
++
+ # FIXUP: The subdirectory for a debug build is NOT the same on all platforms
+ VM_DEBUG=jvmg
+
+ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+
+ # client and server subdirectories have symbolic links to ../libjsig.so
+-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
++EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+ ifneq ($(ZERO_BUILD), true)
+ ifneq ($(OBJCOPY),)
+ ifneq ($(STRIP_POLICY),no_strip)
+@@ -197,7 +200,7 @@
+
+ ifndef BUILD_CLIENT_ONLY
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+ ifneq ($(ZERO_BUILD), true)
+ ifneq ($(OBJCOPY),)
+ ifneq ($(STRIP_POLICY),no_strip)
+@@ -210,7 +213,7 @@
+ ifneq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
+ ifneq ($(OBJCOPY),)
+ ifneq ($(STRIP_POLICY),no_strip)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
+@@ -221,9 +224,9 @@
+
+ # Serviceability Binaries
+ # No SA Support for PPC, IA64, ARM or zero
+-ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so \
++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.so \
++ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+ $(EXPORT_LIB_DIR)/sa-jdi.jar
+ ifneq ($(ZERO_BUILD), true)
+ ifneq ($(OBJCOPY),)
+diff -Nru openjdk.orig/hotspot/make/linux/makefiles/ppc.make openjdk/hotspot/make/linux/makefiles/ppc.make
+--- openjdk.orig/hotspot/make/linux/makefiles/ppc.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/linux/makefiles/ppc.make 2013-04-08 01:49:33.590321620 +0100
+@@ -1,6 +1,25 @@
+ #
+ # Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+-# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
++# 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.
++#
+ #
+
+ # The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
+diff -Nru openjdk.orig/hotspot/make/Makefile openjdk/hotspot/make/Makefile
+--- openjdk.orig/hotspot/make/Makefile 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/Makefile 2013-04-08 01:49:33.594321684 +0100
+@@ -323,28 +323,28 @@
+ ifneq ($(OSNAME),windows)
+ ifeq ($(ZERO_BUILD), true)
+ ifeq ($(SHARK_BUILD), true)
+-$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(SHARK_DIR)/%.so
++$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_SERVER_DIR)/%.so: $(SHARK_DIR)/%.so
++$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+ else
+-$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so
++$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_SERVER_DIR)/%.so: $(ZERO_DIR)/%.so
++$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+ endif
+ else
+-$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C1_DIR)/%.so
++$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C2_DIR)/%.so
++$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_CLIENT_DIR)/%.so: $(C1_DIR)/%.so
++$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_CLIENT_DIR)/64/%.so: $(C1_DIR)/%.so
++$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_SERVER_DIR)/%.so: $(C2_DIR)/%.so
++$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+-$(EXPORT_SERVER_DIR)/64/%.so: $(C2_DIR)/%.so
++$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+ $(install-file)
+
+ # Debug info for shared library
+diff -Nru openjdk.orig/hotspot/make/sa.files openjdk/hotspot/make/sa.files
+--- openjdk.orig/hotspot/make/sa.files 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/sa.files 2013-04-08 01:49:33.594321684 +0100
+@@ -51,6 +51,9 @@
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \
++$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/*.java \
++$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/amd64/*.java \
++$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/x86/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
+@@ -95,6 +98,9 @@
+ AGENT_FILES2 = \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/amd64/*.java \
++$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd/*.java \
++$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_amd64/*.java \
++$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_x86/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ia64/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux/*.java \
+ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \
+diff -Nru openjdk.orig/hotspot/make/solaris/makefiles/defs.make openjdk/hotspot/make/solaris/makefiles/defs.make
+--- openjdk.orig/hotspot/make/solaris/makefiles/defs.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/solaris/makefiles/defs.make 2013-04-08 01:49:33.594321684 +0100
+@@ -134,13 +134,16 @@
+
+ JDK_INCLUDE_SUBDIR=solaris
+
++# Library suffix
++LIBRARY_SUFFIX=so
++
+ # FIXUP: The subdirectory for a debug build is NOT the same on all platforms
+ VM_DEBUG=jvmg
+
+ EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+
+-# client and server subdirectories have symbolic links to ../libjsig.so
+-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
++# client and server subdirectories have symbolic links to ../libjsig.$(LIBRARY_SUFFIX)
++EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+ ifneq ($(OBJCOPY),)
+ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
+ endif
+@@ -150,9 +153,9 @@
+
+ ifneq ($(BUILD_CLIENT_ONLY),true)
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
+-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so
+-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
+ ifneq ($(OBJCOPY),)
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.debuginfo
+@@ -161,11 +164,11 @@
+ endif
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.so
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.so
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+ ifneq ($(OBJCOPY),)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.debuginfo
+@@ -174,8 +177,8 @@
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
+ endif
+ ifneq ($(BUILD_CLIENT_ONLY), true)
+- EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.so
+- EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.so
++ EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
++ EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+ ifneq ($(OBJCOPY),)
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo
+@@ -183,7 +186,7 @@
+ endif
+ endif
+
+-EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
++EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX)
+ ifneq ($(OBJCOPY),)
+ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+ endif
+diff -Nru openjdk.orig/hotspot/make/windows/makefiles/defs.make openjdk/hotspot/make/windows/makefiles/defs.make
+--- openjdk.orig/hotspot/make/windows/makefiles/defs.make 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/make/windows/makefiles/defs.make 2013-04-08 01:49:33.594321684 +0100
+@@ -109,6 +109,9 @@
+
+ JDK_INCLUDE_SUBDIR=win32
+
++# Library suffix
++LIBRARY_SUFFIX=dll
++
+ # HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
+ # and added to MAKE_ARGS list in $(GAMMADIR)/make/defs.make.
+
+@@ -175,24 +178,24 @@
+ EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
+
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+-EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.dll
++EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.dll
++ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map
+ # kernel vm
+ EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
+- EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.dll
++ EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb
+ EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map
+ endif
+
+ ifeq ($(BUILD_WIN_SA), 1)
+- EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.dll
++ EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
+ EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/bytes_x86.hpp openjdk/hotspot/src/cpu/x86/vm/bytes_x86.hpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/bytes_x86.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/bytes_x86.hpp 2013-04-08 01:49:33.594321684 +0100
+@@ -81,6 +81,9 @@
+ #ifdef TARGET_OS_ARCH_windows_x86
+ # include "bytes_windows_x86.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "bytes_bsd_x86.inline.hpp"
++#endif
+
+
+ #endif // CPU_X86_VM_BYTES_X86_HPP
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -427,8 +427,8 @@
+ // Fetch the exception from TLS and clear out exception related thread state
+ __ get_thread(rsi);
+ __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset()));
+- __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
+- __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
++ __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD);
++ __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD);
+
+ __ bind(_unwind_handler_entry);
+ __ verify_not_null_oop(rax);
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/copy_x86.hpp openjdk/hotspot/src/cpu/x86/vm/copy_x86.hpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/copy_x86.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/copy_x86.hpp 2013-04-08 01:49:33.594321684 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_ARCH_windows_x86
+ # include "copy_windows_x86.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "copy_bsd_x86.inline.hpp"
++#endif
+
+
+ static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/globals_x86.hpp openjdk/hotspot/src/cpu/x86/vm/globals_x86.hpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/globals_x86.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/globals_x86.hpp 2013-04-08 01:49:33.594321684 +0100
+@@ -70,7 +70,11 @@
+ define_pd_global(bool, RewriteBytecodes, true);
+ define_pd_global(bool, RewriteFrequentPairs, true);
+
++#ifdef _ALLBSD_SOURCE
++define_pd_global(bool, UseMembar, true);
++#else
+ define_pd_global(bool, UseMembar, false);
++#endif
+
+ // GC Ergo Flags
+ define_pd_global(intx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -45,6 +45,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ // Implementation of InterpreterMacroAssembler
+@@ -1158,7 +1161,7 @@
+ int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
+ set_mdp_data_at(mdp, recvr_offset, receiver);
+ int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
+- movptr(reg2, (int32_t)DataLayout::counter_increment);
++ movptr(reg2, (intptr_t)DataLayout::counter_increment);
+ set_mdp_data_at(mdp, count_offset, reg2);
+ if (start_row > 0) {
+ jmp(done);
+@@ -1301,7 +1304,7 @@
+ test_method_data_pointer(mdp, profile_continue);
+
+ // Build the base (index * per_case_size_in_bytes()) + case_array_offset_in_bytes()
+- movptr(reg2, (int32_t)in_bytes(MultiBranchData::per_case_size()));
++ movptr(reg2, (intptr_t)in_bytes(MultiBranchData::per_case_size()));
+ // index is positive and so should have correct value if this code were
+ // used on 64bits
+ imulptr(index, reg2);
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -45,6 +45,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ // Implementation of InterpreterMacroAssembler
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/jni_x86.h openjdk/hotspot/src/cpu/x86/vm/jni_x86.h
+--- openjdk.orig/hotspot/src/cpu/x86/vm/jni_x86.h 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/jni_x86.h 2013-04-08 01:49:33.594321684 +0100
+@@ -26,7 +26,7 @@
+ #ifndef _JAVASOFT_JNI_MD_H_
+ #define _JAVASOFT_JNI_MD_H_
+
+-#if defined(SOLARIS) || defined(LINUX)
++#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
+
+ #if defined(__GNUC__) && (__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2)
+ #define JNIEXPORT __attribute__((visibility("default")))
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp openjdk/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -47,6 +47,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifdef COMPILER2
+ #include "opto/runtime.hpp"
+ #endif
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp openjdk/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -47,6 +47,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifdef COMPILER2
+ #include "opto/runtime.hpp"
+ #endif
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Implementation of the platform-specific part of StubRoutines - for
+ // a description of how to extend it, see the stubRoutines.hpp file.
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp 2013-04-08 01:49:33.594321684 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Implementation of the platform-specific part of StubRoutines - for
+ // a description of how to extend it, see the stubRoutines.hpp file.
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/vm_version_x86.cpp openjdk/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
+--- openjdk.orig/hotspot/src/cpu/x86/vm/vm_version_x86.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/x86/vm/vm_version_x86.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ int VM_Version::_cpu;
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/bytes_zero.hpp openjdk/hotspot/src/cpu/zero/vm/bytes_zero.hpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/bytes_zero.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/bytes_zero.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -168,6 +168,9 @@
+ #ifdef TARGET_OS_ARCH_linux_zero
+ # include "bytes_linux_zero.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "bytes_bsd_zero.inline.hpp"
++#endif
+
+ #endif // VM_LITTLE_ENDIAN
+
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/globals_zero.hpp openjdk/hotspot/src/cpu/zero/vm/globals_zero.hpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/globals_zero.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/globals_zero.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -52,7 +52,11 @@
+ define_pd_global(bool, RewriteBytecodes, true);
+ define_pd_global(bool, RewriteFrequentPairs, true);
+
++#ifdef _ALLBSD_SOURCE
++define_pd_global(bool, UseMembar, true);
++#else
+ define_pd_global(bool, UseMembar, false);
++#endif
+
+ // GC Ergo Flags
+ define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp openjdk/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -40,5 +40,8 @@
+ #ifdef TARGET_OS_FAMILY_linux
+ # include "thread_linux.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // This file is intentionally empty
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp openjdk/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -43,6 +43,9 @@
+ #ifdef TARGET_OS_FAMILY_linux
+ # include "thread_linux.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifdef COMPILER2
+ #include "opto/runtime.hpp"
+ #endif
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp openjdk/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -30,3 +30,6 @@
+ #ifdef TARGET_OS_FAMILY_linux
+ # include "thread_linux.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/vm_version_zero.cpp openjdk/hotspot/src/cpu/zero/vm/vm_version_zero.cpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/vm_version_zero.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/vm_version_zero.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -32,5 +32,8 @@
+ #ifdef TARGET_OS_FAMILY_linux
+ # include "os_linux.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ // This file is intentionally empty
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/attachListener_bsd.cpp openjdk/hotspot/src/os/bsd/vm/attachListener_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/attachListener_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/attachListener_bsd.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,520 @@
++/*
++ * 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.
++ *
++ */
++
++#include "precompiled.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/os.hpp"
++#include "services/attachListener.hpp"
++#include "services/dtraceAttacher.hpp"
++
++#include <unistd.h>
++#include <signal.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <sys/stat.h>
++
++#ifndef UNIX_PATH_MAX
++#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
++#endif
++
++// The attach mechanism on Bsd uses a UNIX domain socket. An attach listener
++// thread is created at startup or is created on-demand via a signal from
++// the client tool. The attach listener creates a socket and binds it to a file
++// in the filesystem. The attach listener then acts as a simple (single-
++// threaded) server - it waits for a client to connect, reads the request,
++// executes it, and returns the response to the client via the socket
++// connection.
++//
++// As the socket is a UNIX domain socket it means that only clients on the
++// local machine can connect. In addition there are two other aspects to
++// the security:
++// 1. The well known file that the socket is bound to has permission 400
++// 2. When a client connect, the SO_PEERCRED socket option is used to
++// obtain the credentials of client. We check that the effective uid
++// of the client matches this process.
++
++// forward reference
++class BsdAttachOperation;
++
++class BsdAttachListener: AllStatic {
++ private:
++ // the path to which we bind the UNIX domain socket
++ static char _path[UNIX_PATH_MAX];
++ static bool _has_path;
++
++ // the file descriptor for the listening socket
++ static int _listener;
++
++ static void set_path(char* path) {
++ if (path == NULL) {
++ _has_path = false;
++ } else {
++ strncpy(_path, path, UNIX_PATH_MAX);
++ _path[UNIX_PATH_MAX-1] = '\0';
++ _has_path = true;
++ }
++ }
++
++ static void set_listener(int s) { _listener = s; }
++
++ // reads a request from the given connected socket
++ static BsdAttachOperation* read_request(int s);
++
++ public:
++ enum {
++ ATTACH_PROTOCOL_VER = 1 // protocol version
++ };
++ enum {
++ ATTACH_ERROR_BADVERSION = 101 // error codes
++ };
++
++ // initialize the listener, returns 0 if okay
++ static int init();
++
++ static char* path() { return _path; }
++ static bool has_path() { return _has_path; }
++ static int listener() { return _listener; }
++
++ // write the given buffer to a socket
++ static int write_fully(int s, char* buf, int len);
++
++ static BsdAttachOperation* dequeue();
++};
++
++class BsdAttachOperation: public AttachOperation {
++ private:
++ // the connection to the client
++ int _socket;
++
++ public:
++ void complete(jint res, bufferedStream* st);
++
++ void set_socket(int s) { _socket = s; }
++ int socket() const { return _socket; }
++
++ BsdAttachOperation(char* name) : AttachOperation(name) {
++ set_socket(-1);
++ }
++};
++
++// statics
++char BsdAttachListener::_path[UNIX_PATH_MAX];
++bool BsdAttachListener::_has_path;
++int BsdAttachListener::_listener = -1;
++
++// Supporting class to help split a buffer into individual components
++class ArgumentIterator : public StackObj {
++ private:
++ char* _pos;
++ char* _end;
++ public:
++ ArgumentIterator(char* arg_buffer, size_t arg_size) {
++ _pos = arg_buffer;
++ _end = _pos + arg_size - 1;
++ }
++ char* next() {
++ if (*_pos == '\0') {
++ return NULL;
++ }
++ char* res = _pos;
++ char* next_pos = strchr(_pos, '\0');
++ if (next_pos < _end) {
++ next_pos++;
++ }
++ _pos = next_pos;
++ return res;
++ }
++};
++
++
++// atexit hook to stop listener and unlink the file that it is
++// bound too.
++extern "C" {
++ static void listener_cleanup() {
++ static int cleanup_done;
++ if (!cleanup_done) {
++ cleanup_done = 1;
++ int s = BsdAttachListener::listener();
++ if (s != -1) {
++ ::close(s);
++ }
++ if (BsdAttachListener::has_path()) {
++ ::unlink(BsdAttachListener::path());
++ }
++ }
++ }
++}
++
++// Initialization - create a listener socket and bind it to a file
++
++int BsdAttachListener::init() {
++ char path[UNIX_PATH_MAX]; // socket file
++ char initial_path[UNIX_PATH_MAX]; // socket file during setup
++ int listener; // listener socket (file descriptor)
++
++ // register function to cleanup
++ ::atexit(listener_cleanup);
++
++ int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
++ os::get_temp_directory(), os::current_process_id());
++ if (n < (int)UNIX_PATH_MAX) {
++ n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
++ }
++ if (n >= (int)UNIX_PATH_MAX) {
++ return -1;
++ }
++
++ // create the listener socket
++ listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
++ if (listener == -1) {
++ return -1;
++ }
++
++ // bind socket
++ struct sockaddr_un addr;
++ addr.sun_family = AF_UNIX;
++ strcpy(addr.sun_path, initial_path);
++ ::unlink(initial_path);
++ int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
++ if (res == -1) {
++ RESTARTABLE(::close(listener), res);
++ return -1;
++ }
++
++ // put in listen mode, set permissions, and rename into place
++ res = ::listen(listener, 5);
++ if (res == 0) {
++ RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
++ if (res == 0) {
++ res = ::rename(initial_path, path);
++ }
++ }
++ if (res == -1) {
++ RESTARTABLE(::close(listener), res);
++ ::unlink(initial_path);
++ return -1;
++ }
++ set_path(path);
++ set_listener(listener);
++
++ return 0;
++}
++
++// Given a socket that is connected to a peer we read the request and
++// create an AttachOperation. As the socket is blocking there is potential
++// for a denial-of-service if the peer does not response. However this happens
++// after the peer credentials have been checked and in the worst case it just
++// means that the attach listener thread is blocked.
++//
++BsdAttachOperation* BsdAttachListener::read_request(int s) {
++ char ver_str[8];
++ sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
++
++ // The request is a sequence of strings so we first figure out the
++ // expected count and the maximum possible length of the request.
++ // The request is:
++ // <ver>0<cmd>0<arg>0<arg>0<arg>0
++ // where <ver> is the protocol version (1), <cmd> is the command
++ // name ("load", "datadump", ...), and <arg> is an argument
++ int expected_str_count = 2 + AttachOperation::arg_count_max;
++ const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
++ AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
++
++ char buf[max_len];
++ int str_count = 0;
++
++ // Read until all (expected) strings have been read, the buffer is
++ // full, or EOF.
++
++ int off = 0;
++ int left = max_len;
++
++ do {
++ int n;
++ RESTARTABLE(read(s, buf+off, left), n);
++ if (n == -1) {
++ return NULL; // reset by peer or other error
++ }
++ if (n == 0) {
++ break;
++ }
++ for (int i=0; i<n; i++) {
++ if (buf[off+i] == 0) {
++ // EOS found
++ str_count++;
++
++ // The first string is <ver> so check it now to
++ // check for protocol mis-match
++ if (str_count == 1) {
++ if ((strlen(buf) != strlen(ver_str)) ||
++ (atoi(buf) != ATTACH_PROTOCOL_VER)) {
++ char msg[32];
++ sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION);
++ write_fully(s, msg, strlen(msg));
++ return NULL;
++ }
++ }
++ }
++ }
++ off += n;
++ left -= n;
++ } while (left > 0 && str_count < expected_str_count);
++
++ if (str_count != expected_str_count) {
++ return NULL; // incomplete request
++ }
++
++ // parse request
++
++ ArgumentIterator args(buf, (max_len)-left);
++
++ // version already checked
++ char* v = args.next();
++
++ char* name = args.next();
++ if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
++ return NULL;
++ }
++
++ BsdAttachOperation* op = new BsdAttachOperation(name);
++
++ for (int i=0; i<AttachOperation::arg_count_max; i++) {
++ char* arg = args.next();
++ if (arg == NULL) {
++ op->set_arg(i, NULL);
++ } else {
++ if (strlen(arg) > AttachOperation::arg_length_max) {
++ delete op;
++ return NULL;
++ }
++ op->set_arg(i, arg);
++ }
++ }
++
++ op->set_socket(s);
++ return op;
++}
++
++
++// Dequeue an operation
++//
++// In the Bsd implementation there is only a single operation and clients
++// cannot queue commands (except at the socket level).
++//
++BsdAttachOperation* BsdAttachListener::dequeue() {
++ for (;;) {
++ int s;
++
++ // wait for client to connect
++ struct sockaddr addr;
++ socklen_t len = sizeof(addr);
++ RESTARTABLE(::accept(listener(), &addr, &len), s);
++ if (s == -1) {
++ return NULL; // log a warning?
++ }
++
++ // get the credentials of the peer and check the effective uid/guid
++ // - check with jeff on this.
++#ifdef _ALLBSD_SOURCE
++ uid_t puid;
++ gid_t pgid;
++ if (::getpeereid(s, &puid, &pgid) != 0) {
++ int res;
++ RESTARTABLE(::close(s), res);
++ continue;
++ }
++#else
++ struct ucred cred_info;
++ socklen_t optlen = sizeof(cred_info);
++ if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
++ int res;
++ RESTARTABLE(::close(s), res);
++ continue;
++ }
++ uid_t puid = cred_info.uid;
++ gid_t pgid = cred_info.gid;
++#endif
++ uid_t euid = geteuid();
++ gid_t egid = getegid();
++
++ if (puid != euid || pgid != egid) {
++ int res;
++ RESTARTABLE(::close(s), res);
++ continue;
++ }
++
++ // peer credential look okay so we read the request
++ BsdAttachOperation* op = read_request(s);
++ if (op == NULL) {
++ int res;
++ RESTARTABLE(::close(s), res);
++ continue;
++ } else {
++ return op;
++ }
++ }
++}
++
++// write the given buffer to the socket
++int BsdAttachListener::write_fully(int s, char* buf, int len) {
++ do {
++ int n = ::write(s, buf, len);
++ if (n == -1) {
++ if (errno != EINTR) return -1;
++ } else {
++ buf += n;
++ len -= n;
++ }
++ }
++ while (len > 0);
++ return 0;
++}
++
++// Complete an operation by sending the operation result and any result
++// output to the client. At this time the socket is in blocking mode so
++// potentially we can block if there is a lot of data and the client is
++// non-responsive. For most operations this is a non-issue because the
++// default send buffer is sufficient to buffer everything. In the future
++// if there are operations that involves a very big reply then it the
++// socket could be made non-blocking and a timeout could be used.
++
++void BsdAttachOperation::complete(jint result, bufferedStream* st) {
++ JavaThread* thread = JavaThread::current();
++ ThreadBlockInVM tbivm(thread);
++
++ thread->set_suspend_equivalent();
++ // cleared by handle_special_suspend_equivalent_condition() or
++ // java_suspend_self() via check_and_wait_while_suspended()
++
++ // write operation result
++ char msg[32];
++ sprintf(msg, "%d\n", result);
++ int rc = BsdAttachListener::write_fully(this->socket(), msg, strlen(msg));
++
++ // write any result data
++ if (rc == 0) {
++ BsdAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
++ ::shutdown(this->socket(), 2);
++ }
++
++ // done
++ RESTARTABLE(::close(this->socket()), rc);
++
++ // were we externally suspended while we were waiting?
++ thread->check_and_wait_while_suspended();
++
++ delete this;
++}
++
++
++// AttachListener functions
++
++AttachOperation* AttachListener::dequeue() {
++ JavaThread* thread = JavaThread::current();
++ ThreadBlockInVM tbivm(thread);
++
++ thread->set_suspend_equivalent();
++ // cleared by handle_special_suspend_equivalent_condition() or
++ // java_suspend_self() via check_and_wait_while_suspended()
++
++ AttachOperation* op = BsdAttachListener::dequeue();
++
++ // were we externally suspended while we were waiting?
++ thread->check_and_wait_while_suspended();
++
++ return op;
++}
++
++int AttachListener::pd_init() {
++ JavaThread* thread = JavaThread::current();
++ ThreadBlockInVM tbivm(thread);
++
++ thread->set_suspend_equivalent();
++ // cleared by handle_special_suspend_equivalent_condition() or
++ // java_suspend_self() via check_and_wait_while_suspended()
++
++ int ret_code = BsdAttachListener::init();
++
++ // were we externally suspended while we were waiting?
++ thread->check_and_wait_while_suspended();
++
++ return ret_code;
++}
++
++// Attach Listener is started lazily except in the case when
++// +ReduseSignalUsage is used
++bool AttachListener::init_at_startup() {
++ if (ReduceSignalUsage) {
++ return true;
++ } else {
++ return false;
++ }
++}
++
++// If the file .attach_pid<pid> exists in the working directory
++// or /tmp then this is the trigger to start the attach mechanism
++bool AttachListener::is_init_trigger() {
++ if (init_at_startup() || is_initialized()) {
++ return false; // initialized at startup or already initialized
++ }
++ char path[PATH_MAX + 1];
++ int ret;
++ struct stat st;
++
++ snprintf(path, PATH_MAX + 1, "%s/.attach_pid%d",
++ os::get_temp_directory(), os::current_process_id());
++ RESTARTABLE(::stat(path, &st), ret);
++ if (ret == 0) {
++ // simple check to avoid starting the attach mechanism when
++ // a bogus user creates the file
++ if (st.st_uid == geteuid()) {
++ init();
++ return true;
++ }
++ }
++ return false;
++}
++
++// if VM aborts then remove listener
++void AttachListener::abort() {
++ listener_cleanup();
++}
++
++void AttachListener::pd_data_dump() {
++ os::signal_notify(SIGQUIT);
++}
++
++AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) {
++ return NULL;
++}
++
++jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
++ out->print_cr("flag '%s' cannot be changed", op->arg(0));
++ return JNI_ERR;
++}
++
++void AttachListener::pd_detachall() {
++ // do nothing for now
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/c1_globals_bsd.hpp openjdk/hotspot/src/os/bsd/vm/c1_globals_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/c1_globals_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/c1_globals_bsd.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2000, 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_BSD_VM_C1_GLOBALS_BSD_HPP
++#define OS_BSD_VM_C1_GLOBALS_BSD_HPP
++
++#include "utilities/globalDefinitions.hpp"
++#include "utilities/macros.hpp"
++
++//
++// Sets the default values for operating system dependent flags used by the
++// client compiler. (see c1_globals.hpp)
++//
++
++#endif // OS_BSD_VM_C1_GLOBALS_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/c2_globals_bsd.hpp openjdk/hotspot/src/os/bsd/vm/c2_globals_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/c2_globals_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/c2_globals_bsd.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2000, 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_BSD_VM_C2_GLOBALS_BSD_HPP
++#define OS_BSD_VM_C2_GLOBALS_BSD_HPP
++
++#include "utilities/globalDefinitions.hpp"
++#include "utilities/macros.hpp"
++
++//
++// Sets the default values for operating system dependent flags used by the
++// server compiler. (see c2_globals.hpp)
++//
++
++#endif // OS_BSD_VM_C2_GLOBALS_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/chaitin_bsd.cpp openjdk/hotspot/src/os/bsd/vm/chaitin_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/chaitin_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/chaitin_bsd.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 1999, 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 "precompiled.hpp"
++#include "opto/chaitin.hpp"
++#include "opto/machnode.hpp"
++
++void PhaseRegAlloc::pd_preallocate_hook() {
++ // no action
++}
++
++#ifdef ASSERT
++void PhaseRegAlloc::pd_postallocate_verify_hook() {
++ // no action
++}
++#endif
++
++
++// Reconciliation History
++// chaitin_solaris.cpp 1.7 99/07/12 23:54:22
++// End
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/decoder_bsd.cpp openjdk/hotspot/src/os/bsd/vm/decoder_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/decoder_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/decoder_bsd.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (c) 1997, 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 "prims/jvm.h"
++#include "utilities/decoder.hpp"
++
++#include <cxxabi.h>
++
++#ifdef __APPLE__
++
++void Decoder::initialize() {
++ _initialized = true;
++}
++
++void Decoder::uninitialize() {
++ _initialized = false;
++}
++
++bool Decoder::can_decode_C_frame_in_vm() {
++ return false;
++}
++
++Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
++ return symbol_not_found;
++}
++
++
++#endif
++
++bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
++ int status;
++ char* result;
++ size_t size = (size_t)buflen;
++
++ // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
++ // __cxa_demangle will call system "realloc" for additional memory, which
++ // may use different malloc/realloc mechanism that allocates 'buf'.
++ if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
++ jio_snprintf(buf, buflen, "%s", result);
++ // call c library's free
++ ::free(result);
++ return true;
++ }
++ return false;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp openjdk/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 1997, 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 "precompiled.hpp"
++#include "classfile/javaClasses.hpp"
++#include "code/codeBlob.hpp"
++#include "memory/allocation.hpp"
++#include "prims/jvm.h"
++#include "runtime/dtraceJSDT.hpp"
++#include "runtime/jniHandles.hpp"
++#include "runtime/os.hpp"
++#include "runtime/signature.hpp"
++#include "utilities/globalDefinitions.hpp"
++
++int DTraceJSDT::pd_activate(
++ void* baseAddress, jstring module,
++ jint providers_count, JVM_DTraceProvider* providers) {
++ return -1;
++}
++
++void DTraceJSDT::pd_dispose(int handle) {
++}
++
++jboolean DTraceJSDT::pd_is_supported() {
++ return false;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/globals_bsd.hpp openjdk/hotspot/src/os/bsd/vm/globals_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/globals_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/globals_bsd.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (c) 2005, 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.
++ *
++ */
++
++#ifndef OS_BSD_VM_GLOBALS_BSD_HPP
++#define OS_BSD_VM_GLOBALS_BSD_HPP
++
++//
++// Defines Bsd specific flags. They are not available on other platforms.
++//
++#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
++ product(bool, UseOprofile, false, \
++ "enable support for Oprofile profiler") \
++ \
++ product(bool, UseBsdPosixThreadCPUClocks, true, \
++ "enable fast Bsd Posix clocks where available") \
++/* NB: The default value of UseBsdPosixThreadCPUClocks may be \
++ overridden in Arguments::parse_each_vm_init_arg. */ \
++ \
++ product(bool, UseHugeTLBFS, false, \
++ "Use MAP_HUGETLB for large pages") \
++ \
++ product(bool, UseSHM, false, \
++ "Use SYSV shared memory for large pages")
++
++//
++// Defines Bsd-specific default values. The flags are available on all
++// platforms, but they may have different default values on other platforms.
++//
++define_pd_global(bool, UseLargePages, false);
++define_pd_global(bool, UseLargePagesIndividualAllocation, false);
++define_pd_global(bool, UseOSErrorReporting, false);
++define_pd_global(bool, UseThreadPriorities, true) ;
++
++#endif // OS_BSD_VM_GLOBALS_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/interfaceSupport_bsd.hpp openjdk/hotspot/src/os/bsd/vm/interfaceSupport_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/interfaceSupport_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/interfaceSupport_bsd.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,34 @@
++/*
++ * 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.
++ *
++ */
++
++#ifndef OS_BSD_VM_INTERFACESUPPORT_BSD_HPP
++#define OS_BSD_VM_INTERFACESUPPORT_BSD_HPP
++
++// Contains inlined functions for class InterfaceSupport
++
++static inline void serialize_memory(JavaThread *thread) {
++ os::write_memory_serialize_page(thread);
++}
++
++#endif // OS_BSD_VM_INTERFACESUPPORT_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/jsig.c openjdk/hotspot/src/os/bsd/vm/jsig.c
+--- openjdk.orig/hotspot/src/os/bsd/vm/jsig.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/jsig.c 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,225 @@
++/*
++ * Copyright (c) 2001, 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.
++ *
++ */
++
++/* CopyrightVersion 1.2 */
++
++/* This is a special library that should be loaded before libc &
++ * libthread to interpose the signal handler installation functions:
++ * sigaction(), signal(), sigset().
++ * Used for signal-chaining. See RFE 4381843.
++ */
++
++#include <signal.h>
++#include <dlfcn.h>
++#include <pthread.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdbool.h>
++
++#define MAXSIGNUM 32
++#define MASK(sig) ((unsigned int)1 << sig)
++
++static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
++static unsigned int jvmsigs = 0; /* signals used by jvm */
++
++/* used to synchronize the installation of signal handlers */
++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
++static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
++static pthread_t tid = 0;
++
++typedef void (*sa_handler_t)(int);
++typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
++typedef sa_handler_t (*signal_t)(int, sa_handler_t);
++typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
++
++static signal_t os_signal = 0; /* os's version of signal()/sigset() */
++static sigaction_t os_sigaction = 0; /* os's version of sigaction() */
++
++static bool jvm_signal_installing = false;
++static bool jvm_signal_installed = false;
++
++static void signal_lock() {
++ pthread_mutex_lock(&mutex);
++ /* When the jvm is installing its set of signal handlers, threads
++ * other than the jvm thread should wait */
++ if (jvm_signal_installing) {
++ if (tid != pthread_self()) {
++ pthread_cond_wait(&cond, &mutex);
++ }
++ }
++}
++
++static void signal_unlock() {
++ pthread_mutex_unlock(&mutex);
++}
++
++static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
++ bool is_sigset) {
++ if (os_signal == NULL) {
++ if (!is_sigset) {
++ os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
++ } else {
++ os_signal = (signal_t)dlsym(RTLD_NEXT, "sigset");
++ }
++ if (os_signal == NULL) {
++ printf("%s\n", dlerror());
++ exit(0);
++ }
++ }
++ return (*os_signal)(sig, disp);
++}
++
++static void save_signal_handler(int sig, sa_handler_t disp) {
++ sigset_t set;
++ sact[sig].sa_handler = disp;
++ sigemptyset(&set);
++ sact[sig].sa_mask = set;
++ sact[sig].sa_flags = 0;
++}
++
++static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
++ sa_handler_t oldhandler;
++ bool sigused;
++
++ signal_lock();
++
++ sigused = (MASK(sig) & jvmsigs) != 0;
++ if (jvm_signal_installed && sigused) {
++ /* jvm has installed its signal handler for this signal. */
++ /* Save the handler. Don't really install it. */
++ oldhandler = sact[sig].sa_handler;
++ save_signal_handler(sig, disp);
++
++ signal_unlock();
++ return oldhandler;
++ } else if (jvm_signal_installing) {
++ /* jvm is installing its signal handlers. Install the new
++ * handlers and save the old ones. jvm uses sigaction().
++ * Leave the piece here just in case. */
++ oldhandler = call_os_signal(sig, disp, is_sigset);
++ save_signal_handler(sig, oldhandler);
++
++ /* Record the signals used by jvm */
++ jvmsigs |= MASK(sig);
++
++ signal_unlock();
++ return oldhandler;
++ } else {
++ /* jvm has no relation with this signal (yet). Install the
++ * the handler. */
++ oldhandler = call_os_signal(sig, disp, is_sigset);
++
++ signal_unlock();
++ return oldhandler;
++ }
++}
++
++sa_handler_t signal(int sig, sa_handler_t disp) {
++ return set_signal(sig, disp, false);
++}
++
++sa_handler_t sigset(int sig, sa_handler_t disp) {
++ printf("sigset() is not supported by BSD");
++ exit(0);
++ }
++
++static int call_os_sigaction(int sig, const struct sigaction *act,
++ struct sigaction *oact) {
++ if (os_sigaction == NULL) {
++ os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction");
++ if (os_sigaction == NULL) {
++ printf("%s\n", dlerror());
++ exit(0);
++ }
++ }
++ return (*os_sigaction)(sig, act, oact);
++}
++
++int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
++ int res;
++ bool sigused;
++ struct sigaction oldAct;
++
++ signal_lock();
++
++ sigused = (MASK(sig) & jvmsigs) != 0;
++ if (jvm_signal_installed && sigused) {
++ /* jvm has installed its signal handler for this signal. */
++ /* Save the handler. Don't really install it. */
++ if (oact != NULL) {
++ *oact = sact[sig];
++ }
++ if (act != NULL) {
++ sact[sig] = *act;
++ }
++
++ signal_unlock();
++ return 0;
++ } else if (jvm_signal_installing) {
++ /* jvm is installing its signal handlers. Install the new
++ * handlers and save the old ones. */
++ res = call_os_sigaction(sig, act, &oldAct);
++ sact[sig] = oldAct;
++ if (oact != NULL) {
++ *oact = oldAct;
++ }
++
++ /* Record the signals used by jvm */
++ jvmsigs |= MASK(sig);
++
++ signal_unlock();
++ return res;
++ } else {
++ /* jvm has no relation with this signal (yet). Install the
++ * the handler. */
++ res = call_os_sigaction(sig, act, oact);
++
++ signal_unlock();
++ return res;
++ }
++}
++
++/* The three functions for the jvm to call into */
++void JVM_begin_signal_setting() {
++ signal_lock();
++ jvm_signal_installing = true;
++ tid = pthread_self();
++ signal_unlock();
++}
++
++void JVM_end_signal_setting() {
++ signal_lock();
++ jvm_signal_installed = true;
++ jvm_signal_installing = false;
++ pthread_cond_broadcast(&cond);
++ signal_unlock();
++}
++
++struct sigaction *JVM_get_signal_action(int sig) {
++ /* Does race condition make sense here? */
++ if ((MASK(sig) & jvmsigs) != 0) {
++ return &sact[sig];
++ }
++ return NULL;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/jvm_bsd.cpp openjdk/hotspot/src/os/bsd/vm/jvm_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/jvm_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/jvm_bsd.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,192 @@
++/*
++ * Copyright (c) 1999, 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 "precompiled.hpp"
++#include "prims/jvm.h"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/osThread.hpp"
++
++#include <signal.h>
++
++
++// sun.misc.Signal ///////////////////////////////////////////////////////////
++// Signal code is mostly copied from classic vm, signals_md.c 1.4 98/08/23
++/*
++ * This function is included primarily as a debugging aid. If Java is
++ * running in a console window, then pressing <CTRL-\\> will cause
++ * the current state of all active threads and monitors to be written
++ * to the console window.
++ */
++
++JVM_ENTRY_NO_ENV(void*, JVM_RegisterSignal(jint sig, void* handler))
++ // Copied from classic vm
++ // signals_md.c 1.4 98/08/23
++ void* newHandler = handler == (void *)2
++ ? os::user_handler()
++ : handler;
++ switch (sig) {
++ /* The following are already used by the VM. */
++ case INTERRUPT_SIGNAL:
++ case SIGFPE:
++ case SIGILL:
++ case SIGSEGV:
++
++ /* The following signal is used by the VM to dump thread stacks unless
++ ReduceSignalUsage is set, in which case the user is allowed to set
++ his own _native_ handler for this signal; thus, in either case,
++ we do not allow JVM_RegisterSignal to change the handler. */
++ case BREAK_SIGNAL:
++ return (void *)-1;
++
++ /* The following signals are used for Shutdown Hooks support. However, if
++ ReduceSignalUsage (-Xrs) is set, Shutdown Hooks must be invoked via
++ System.exit(), Java is not allowed to use these signals, and the the
++ user is allowed to set his own _native_ handler for these signals and
++ invoke System.exit() as needed. Terminator.setup() is avoiding
++ registration of these signals when -Xrs is present.
++ - If the HUP signal is ignored (from the nohup) command, then Java
++ is not allowed to use this signal.
++ */
++
++ case SHUTDOWN1_SIGNAL:
++ case SHUTDOWN2_SIGNAL:
++ case SHUTDOWN3_SIGNAL:
++ if (ReduceSignalUsage) return (void*)-1;
++ if (os::Bsd::is_sig_ignored(sig)) return (void*)1;
++ }
++
++ void* oldHandler = os::signal(sig, newHandler);
++ if (oldHandler == os::user_handler()) {
++ return (void *)2;
++ } else {
++ return oldHandler;
++ }
++JVM_END
++
++
++JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
++ if (ReduceSignalUsage) {
++ // do not allow SHUTDOWN1_SIGNAL,SHUTDOWN2_SIGNAL,SHUTDOWN3_SIGNAL,
++ // BREAK_SIGNAL to be raised when ReduceSignalUsage is set, since
++ // no handler for them is actually registered in JVM or via
++ // JVM_RegisterSignal.
++ if (sig == SHUTDOWN1_SIGNAL || sig == SHUTDOWN2_SIGNAL ||
++ sig == SHUTDOWN3_SIGNAL || sig == BREAK_SIGNAL) {
++ return JNI_FALSE;
++ }
++ }
++ else if ((sig == SHUTDOWN1_SIGNAL || sig == SHUTDOWN2_SIGNAL ||
++ sig == SHUTDOWN3_SIGNAL) && os::Bsd::is_sig_ignored(sig)) {
++ // do not allow SHUTDOWN1_SIGNAL to be raised when SHUTDOWN1_SIGNAL
++ // is ignored, since no handler for them is actually registered in JVM
++ // or via JVM_RegisterSignal.
++ // This also applies for SHUTDOWN2_SIGNAL and SHUTDOWN3_SIGNAL
++ return JNI_FALSE;
++ }
++
++ os::signal_raise(sig);
++ return JNI_TRUE;
++JVM_END
++
++/*
++ All the defined signal names for Bsd.
++
++ NOTE that not all of these names are accepted by our Java implementation
++
++ Via an existing claim by the VM, sigaction restrictions, or
++ the "rules of Unix" some of these names will be rejected at runtime.
++ For example the VM sets up to handle USR1, sigaction returns EINVAL for
++ STOP, and Bsd simply doesn't allow catching of KILL.
++
++ Here are the names currently accepted by a user of sun.misc.Signal with
++ 1.4.1 (ignoring potential interaction with use of chaining, etc):
++
++ HUP, INT, TRAP, ABRT, IOT, BUS, USR2, PIPE, ALRM, TERM, STKFLT,
++ CLD, CHLD, CONT, TSTP, TTIN, TTOU, URG, XCPU, XFSZ, VTALRM, PROF,
++ WINCH, POLL, IO, PWR, SYS
++
++*/
++
++struct siglabel {
++ const char *name;
++ int number;
++};
++
++struct siglabel siglabels[] = {
++ /* derived from /usr/include/bits/signum.h on RH7.2 */
++ "HUP", SIGHUP, /* Hangup (POSIX). */
++ "INT", SIGINT, /* Interrupt (ANSI). */
++ "QUIT", SIGQUIT, /* Quit (POSIX). */
++ "ILL", SIGILL, /* Illegal instruction (ANSI). */
++ "TRAP", SIGTRAP, /* Trace trap (POSIX). */
++ "ABRT", SIGABRT, /* Abort (ANSI). */
++ "EMT", SIGEMT, /* EMT trap */
++ "FPE", SIGFPE, /* Floating-point exception (ANSI). */
++ "KILL", SIGKILL, /* Kill, unblockable (POSIX). */
++ "BUS", SIGBUS, /* BUS error (4.2 BSD). */
++ "SEGV", SIGSEGV, /* Segmentation violation (ANSI). */
++ "SYS", SIGSYS, /* Bad system call. Only on some Bsden! */
++ "PIPE", SIGPIPE, /* Broken pipe (POSIX). */
++ "ALRM", SIGALRM, /* Alarm clock (POSIX). */
++ "TERM", SIGTERM, /* Termination (ANSI). */
++ "URG", SIGURG, /* Urgent condition on socket (4.2 BSD). */
++ "STOP", SIGSTOP, /* Stop, unblockable (POSIX). */
++ "TSTP", SIGTSTP, /* Keyboard stop (POSIX). */
++ "CONT", SIGCONT, /* Continue (POSIX). */
++ "CHLD", SIGCHLD, /* Child status has changed (POSIX). */
++ "TTIN", SIGTTIN, /* Background read from tty (POSIX). */
++ "TTOU", SIGTTOU, /* Background write to tty (POSIX). */
++ "IO", SIGIO, /* I/O now possible (4.2 BSD). */
++ "XCPU", SIGXCPU, /* CPU limit exceeded (4.2 BSD). */
++ "XFSZ", SIGXFSZ, /* File size limit exceeded (4.2 BSD). */
++ "VTALRM", SIGVTALRM, /* Virtual alarm clock (4.2 BSD). */
++ "PROF", SIGPROF, /* Profiling alarm clock (4.2 BSD). */
++ "WINCH", SIGWINCH, /* Window size change (4.3 BSD, Sun). */
++ "INFO", SIGINFO, /* Information request. */
++ "USR1", SIGUSR1, /* User-defined signal 1 (POSIX). */
++ "USR2", SIGUSR2 /* User-defined signal 2 (POSIX). */
++ };
++
++JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
++
++ /* find and return the named signal's number */
++
++ for(uint i=0; i<ARRAY_SIZE(siglabels); i++)
++ if(!strcmp(name, siglabels[i].name))
++ return siglabels[i].number;
++
++ return -1;
++
++JVM_END
++
++// used by os::exception_name()
++extern bool signal_name(int signo, char* buf, size_t len) {
++ for(uint i = 0; i < ARRAY_SIZE(siglabels); i++) {
++ if (signo == siglabels[i].number) {
++ jio_snprintf(buf, len, "SIG%s", siglabels[i].name);
++ return true;
++ }
++ }
++ return false;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/jvm_bsd.h openjdk/hotspot/src/os/bsd/vm/jvm_bsd.h
+--- openjdk.orig/hotspot/src/os/bsd/vm/jvm_bsd.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/jvm_bsd.h 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (c) 1999, 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_BSD_VM_JVM_BSD_H
++#define OS_BSD_VM_JVM_BSD_H
++
++/*
++// HotSpot integration note:
++//
++// This is derived from the JDK classic file:
++// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22)
++// All local includes have been commented out.
++*/
++
++
++#ifndef JVM_MD_H
++#define JVM_MD_H
++
++/*
++ * This file is currently collecting system-specific dregs for the
++ * JNI conversion, which should be sorted out later.
++ */
++
++#include <dirent.h> /* For DIR */
++#include <sys/param.h> /* For MAXPATHLEN */
++#include <unistd.h> /* For F_OK, R_OK, W_OK */
++
++#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"}
++#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"}
++#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"}
++#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"}
++#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"}
++#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"}
++
++#define JNI_LIB_PREFIX "lib"
++#ifdef __APPLE__
++#define JNI_LIB_SUFFIX ".dylib"
++#else
++#define JNI_LIB_SUFFIX ".so"
++#endif
++
++// Hack: MAXPATHLEN is 4095 on some Bsd and 4096 on others. This may
++// cause problems if JVM and the rest of JDK are built on different
++// Bsd releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1,
++// so buffers declared in VM are always >= 4096.
++#define JVM_MAXPATHLEN MAXPATHLEN + 1
++
++#define JVM_R_OK R_OK
++#define JVM_W_OK W_OK
++#define JVM_X_OK X_OK
++#define JVM_F_OK F_OK
++
++/*
++ * File I/O
++ */
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++
++/* O Flags */
++
++#define JVM_O_RDONLY O_RDONLY
++#define JVM_O_WRONLY O_WRONLY
++#define JVM_O_RDWR O_RDWR
++#define JVM_O_O_APPEND O_APPEND
++#define JVM_O_EXCL O_EXCL
++#define JVM_O_CREAT O_CREAT
++
++/* Signal definitions */
++
++#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */
++#define INTERRUPT_SIGNAL SIGUSR1 /* Interruptible I/O support. */
++#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */
++#define SHUTDOWN2_SIGNAL SIGINT
++#define SHUTDOWN3_SIGNAL SIGTERM
++
++#ifndef SIGRTMIN
++#ifdef __OpenBSD__
++#define SIGRTMIN 1
++#else
++#define SIGRTMIN 33
++#endif
++#endif
++#ifndef SIGRTMAX
++#ifdef __OpenBSD__
++#define SIGRTMAX 31
++#else
++#define SIGRTMAX 63
++#endif
++#endif
++#endif /* JVM_MD_H */
++
++// Reconciliation History
++// jvm_solaris.h 1.6 99/06/22 16:38:47
++// End
++
++#endif // OS_BSD_VM_JVM_BSD_H
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/mutex_bsd.cpp openjdk/hotspot/src/os/bsd/vm/mutex_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/mutex_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/mutex_bsd.cpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2007, 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 "precompiled.hpp"
++#include "mutex_bsd.inline.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/mutex.hpp"
++#include "thread_bsd.inline.hpp"
++#include "utilities/events.hpp"
++
++// put OS-includes here
++# include <signal.h>
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/mutex_bsd.inline.hpp openjdk/hotspot/src/os/bsd/vm/mutex_bsd.inline.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/mutex_bsd.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/mutex_bsd.inline.hpp 2013-04-08 01:49:33.598321747 +0100
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 1999, 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_BSD_VM_MUTEX_BSD_INLINE_HPP
++#define OS_BSD_VM_MUTEX_BSD_INLINE_HPP
++
++#include "os_bsd.inline.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "thread_bsd.inline.hpp"
++
++
++// Reconciliation History
++// mutex_solaris.inline.hpp 1.5 99/06/22 16:38:49
++// End
++
++#endif // OS_BSD_VM_MUTEX_BSD_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.cpp openjdk/hotspot/src/os/bsd/vm/os_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/os_bsd.cpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,5709 @@
++/*
++ * Copyright (c) 1999, 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.
++ *
++ */
++
++// no precompiled headers
++#include "classfile/classLoader.hpp"
++#include "classfile/systemDictionary.hpp"
++#include "classfile/vmSymbols.hpp"
++#include "code/icBuffer.hpp"
++#include "code/vtableStubs.hpp"
++#include "compiler/compileBroker.hpp"
++#include "interpreter/interpreter.hpp"
++#include "jvm_bsd.h"
++#include "memory/allocation.inline.hpp"
++#include "memory/filemap.hpp"
++#include "mutex_bsd.inline.hpp"
++#include "oops/oop.inline.hpp"
++#include "os_share_bsd.hpp"
++#include "prims/jniFastGetField.hpp"
++#include "prims/jvm.h"
++#include "prims/jvm_misc.hpp"
++#include "runtime/arguments.hpp"
++#include "runtime/extendedPC.hpp"
++#include "runtime/globals.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/java.hpp"
++#include "runtime/javaCalls.hpp"
++#include "runtime/mutexLocker.hpp"
++#include "runtime/objectMonitor.hpp"
++#include "runtime/osThread.hpp"
++#include "runtime/perfMemory.hpp"
++#include "runtime/sharedRuntime.hpp"
++#include "runtime/statSampler.hpp"
++#include "runtime/stubRoutines.hpp"
++#include "runtime/threadCritical.hpp"
++#include "runtime/timer.hpp"
++#include "services/attachListener.hpp"
++#include "services/runtimeService.hpp"
++#include "thread_bsd.inline.hpp"
++#include "utilities/decoder.hpp"
++#include "utilities/defaultStream.hpp"
++#include "utilities/events.hpp"
++#include "utilities/growableArray.hpp"
++#include "utilities/vmError.hpp"
++#ifdef TARGET_ARCH_x86
++# include "assembler_x86.inline.hpp"
++# include "nativeInst_x86.hpp"
++#endif
++#ifdef TARGET_ARCH_sparc
++# include "assembler_sparc.inline.hpp"
++# include "nativeInst_sparc.hpp"
++#endif
++#ifdef TARGET_ARCH_zero
++# include "assembler_zero.inline.hpp"
++# include "nativeInst_zero.hpp"
++#endif
++#ifdef TARGET_ARCH_arm
++# include "assembler_arm.inline.hpp"
++# include "nativeInst_arm.hpp"
++#endif
++#ifdef TARGET_ARCH_ppc
++# include "assembler_ppc.inline.hpp"
++# include "nativeInst_ppc.hpp"
++#endif
++#ifdef COMPILER1
++#include "c1/c1_Runtime1.hpp"
++#endif
++#ifdef COMPILER2
++#include "opto/runtime.hpp"
++#endif
++
++// put OS-includes here
++# include <sys/types.h>
++# include <sys/mman.h>
++# include <sys/stat.h>
++# include <sys/select.h>
++# include <pthread.h>
++# include <signal.h>
++# include <errno.h>
++# include <dlfcn.h>
++# include <stdio.h>
++# include <unistd.h>
++# include <sys/resource.h>
++# include <pthread.h>
++# include <sys/stat.h>
++# include <sys/time.h>
++# include <sys/times.h>
++# include <sys/utsname.h>
++# include <sys/socket.h>
++# include <sys/wait.h>
++# include <time.h>
++# include <pwd.h>
++# include <poll.h>
++# include <semaphore.h>
++# include <fcntl.h>
++# include <string.h>
++#ifdef _ALLBSD_SOURCE
++# include <sys/param.h>
++# include <sys/sysctl.h>
++#else
++# include <syscall.h>
++# include <sys/sysinfo.h>
++# include <gnu/libc-version.h>
++#endif
++# include <sys/ipc.h>
++# include <sys/shm.h>
++#ifndef __APPLE__
++# include <link.h>
++#endif
++# include <stdint.h>
++# include <inttypes.h>
++# include <sys/ioctl.h>
++
++#if defined(__FreeBSD__) || defined(__NetBSD__)
++# include <elf.h>
++#endif
++
++#ifdef __APPLE__
++#include <mach/mach.h> // semaphore_* API
++#include <mach-o/dyld.h>
++#endif
++
++#ifndef MAP_ANONYMOUS
++#define MAP_ANONYMOUS MAP_ANON
++#endif
++
++#define MAX_PATH (2 * K)
++
++// for timer info max values which include all bits
++#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
++#define SEC_IN_NANOSECS 1000000000LL
++
++#define LARGEPAGES_BIT (1 << 6)
++////////////////////////////////////////////////////////////////////////////////
++// global variables
++julong os::Bsd::_physical_memory = 0;
++
++#ifndef _ALLBSD_SOURCE
++address os::Bsd::_initial_thread_stack_bottom = NULL;
++uintptr_t os::Bsd::_initial_thread_stack_size = 0;
++#endif
++
++int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
++#ifndef _ALLBSD_SOURCE
++int (*os::Bsd::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
++Mutex* os::Bsd::_createThread_lock = NULL;
++#endif
++pthread_t os::Bsd::_main_thread;
++int os::Bsd::_page_size = -1;
++#ifndef _ALLBSD_SOURCE
++bool os::Bsd::_is_floating_stack = false;
++bool os::Bsd::_is_NPTL = false;
++bool os::Bsd::_supports_fast_thread_cpu_time = false;
++const char * os::Bsd::_glibc_version = NULL;
++const char * os::Bsd::_libpthread_version = NULL;
++#endif
++
++static jlong initial_time_count=0;
++
++static int clock_tics_per_sec = 100;
++
++// For diagnostics to print a message once. see run_periodic_checks
++static sigset_t check_signal_done;
++static bool check_signals = true;;
++
++static pid_t _initial_pid = 0;
++
++/* Signal number used to suspend/resume a thread */
++
++/* do not use any signal number less than SIGSEGV, see 4355769 */
++static int SR_signum = SIGUSR2;
++sigset_t SR_sigset;
++
++
++////////////////////////////////////////////////////////////////////////////////
++// utility functions
++
++static int SR_initialize();
++static int SR_finalize();
++
++julong os::available_memory() {
++ return Bsd::available_memory();
++}
++
++julong os::Bsd::available_memory() {
++#ifdef _ALLBSD_SOURCE
++ // XXXBSD: this is just a stopgap implementation
++ return physical_memory() >> 2;
++#else
++ // values in struct sysinfo are "unsigned long"
++ struct sysinfo si;
++ sysinfo(&si);
++
++ return (julong)si.freeram * si.mem_unit;
++#endif
++}
++
++julong os::physical_memory() {
++ return Bsd::physical_memory();
++}
++
++julong os::allocatable_physical_memory(julong size) {
++#ifdef _LP64
++ return size;
++#else
++ julong result = MIN2(size, (julong)3800*M);
++ if (!is_allocatable(result)) {
++ // See comments under solaris for alignment considerations
++ julong reasonable_size = (julong)2*G - 2 * os::vm_page_size();
++ result = MIN2(size, reasonable_size);
++ }
++ return result;
++#endif // _LP64
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// environment support
++
++bool os::getenv(const char* name, char* buf, int len) {
++ const char* val = ::getenv(name);
++ if (val != NULL && strlen(val) < (size_t)len) {
++ strcpy(buf, val);
++ return true;
++ }
++ if (len > 0) buf[0] = 0; // return a null string
++ return false;
++}
++
++
++// Return true if user is running as root.
++
++bool os::have_special_privileges() {
++ static bool init = false;
++ static bool privileges = false;
++ if (!init) {
++ privileges = (getuid() != geteuid()) || (getgid() != getegid());
++ init = true;
++ }
++ return privileges;
++}
++
++
++#ifndef _ALLBSD_SOURCE
++#ifndef SYS_gettid
++// i386: 224, ia64: 1105, amd64: 186, sparc 143
++#ifdef __ia64__
++#define SYS_gettid 1105
++#elif __i386__
++#define SYS_gettid 224
++#elif __amd64__
++#define SYS_gettid 186
++#elif __sparc__
++#define SYS_gettid 143
++#else
++#error define gettid for the arch
++#endif
++#endif
++#endif
++
++// Cpu architecture string
++#if defined(ZERO)
++static char cpu_arch[] = ZERO_LIBARCH;
++#elif defined(IA64)
++static char cpu_arch[] = "ia64";
++#elif defined(IA32)
++static char cpu_arch[] = "i386";
++#elif defined(AMD64)
++static char cpu_arch[] = "amd64";
++#elif defined(ARM)
++static char cpu_arch[] = "arm";
++#elif defined(PPC)
++static char cpu_arch[] = "ppc";
++#elif defined(SPARC)
++# ifdef _LP64
++static char cpu_arch[] = "sparcv9";
++# else
++static char cpu_arch[] = "sparc";
++# endif
++#else
++#error Add appropriate cpu_arch setting
++#endif
++
++
++#ifndef _ALLBSD_SOURCE
++// pid_t gettid()
++//
++// Returns the kernel thread id of the currently running thread. Kernel
++// thread id is used to access /proc.
++//
++// (Note that getpid() on BsdThreads returns kernel thread id too; but
++// on NPTL, it returns the same pid for all threads, as required by POSIX.)
++//
++pid_t os::Bsd::gettid() {
++ int rslt = syscall(SYS_gettid);
++ if (rslt == -1) {
++ // old kernel, no NPTL support
++ return getpid();
++ } else {
++ return (pid_t)rslt;
++ }
++}
++
++// Most versions of bsd have a bug where the number of processors are
++// determined by looking at the /proc file system. In a chroot environment,
++// the system call returns 1. This causes the VM to act as if it is
++// a single processor and elide locking (see is_MP() call).
++static bool unsafe_chroot_detected = false;
++static const char *unstable_chroot_error = "/proc file system not found.\n"
++ "Java may be unstable running multithreaded in a chroot "
++ "environment on Bsd when /proc filesystem is not mounted.";
++#endif
++
++#ifdef _ALLBSD_SOURCE
++void os::Bsd::initialize_system_info() {
++ int mib[2];
++ size_t len;
++ int cpu_val;
++ u_long mem_val;
++
++ /* get processors count via hw.ncpus sysctl */
++ mib[0] = CTL_HW;
++ mib[1] = HW_NCPU;
++ len = sizeof(cpu_val);
++ if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) {
++ set_processor_count(cpu_val);
++ }
++ else {
++ set_processor_count(1); // fallback
++ }
++
++ /* get physical memory via hw.usermem sysctl (hw.usermem is used
++ * instead of hw.physmem because we need size of allocatable memory
++ */
++ mib[0] = CTL_HW;
++ mib[1] = HW_USERMEM;
++ len = sizeof(mem_val);
++ if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1)
++ _physical_memory = mem_val;
++ else
++ _physical_memory = 256*1024*1024; // fallback (XXXBSD?)
++
++#ifdef __OpenBSD__
++ {
++ // limit _physical_memory memory view on OpenBSD since
++ // datasize rlimit restricts us anyway.
++ struct rlimit limits;
++ getrlimit(RLIMIT_DATA, &limits);
++ _physical_memory = MIN2(_physical_memory, (julong)limits.rlim_cur);
++ }
++#endif
++}
++#else
++void os::Bsd::initialize_system_info() {
++ set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
++ if (processor_count() == 1) {
++ pid_t pid = os::Bsd::gettid();
++ char fname[32];
++ jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
++ FILE *fp = fopen(fname, "r");
++ if (fp == NULL) {
++ unsafe_chroot_detected = true;
++ } else {
++ fclose(fp);
++ }
++ }
++ _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
++ assert(processor_count() > 0, "bsd error");
++}
++#endif
++
++void os::init_system_properties_values() {
++// char arch[12];
++// sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
++
++ // The next steps are taken in the product version:
++ //
++ // Obtain the JAVA_HOME value from the location of libjvm[_g].so.
++ // This library should be located at:
++ // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm[_g].so.
++ //
++ // If "/jre/lib/" appears at the right place in the path, then we
++ // assume libjvm[_g].so is installed in a JDK and we use this path.
++ //
++ // Otherwise exit with message: "Could not create the Java virtual machine."
++ //
++ // The following extra steps are taken in the debugging version:
++ //
++ // If "/jre/lib/" does NOT appear at the right place in the path
++ // instead of exit check for $JAVA_HOME environment variable.
++ //
++ // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
++ // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so
++ // it looks like libjvm[_g].so is installed there
++ // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm[_g].so.
++ //
++ // Otherwise exit.
++ //
++ // Important note: if the location of libjvm.so changes this
++ // code needs to be changed accordingly.
++
++ // The next few definitions allow the code to be verbatim:
++#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
++#define getenv(n) ::getenv(n)
++
++/*
++ * See ld(1):
++ * The linker uses the following search paths to locate required
++ * shared libraries:
++ * 1: ...
++ * ...
++ * 7: The default directories, normally /lib and /usr/lib.
++ */
++#ifndef DEFAULT_LIBPATH
++#define DEFAULT_LIBPATH "/lib:/usr/lib"
++#endif
++
++#define EXTENSIONS_DIR "/lib/ext"
++#define ENDORSED_DIR "/lib/endorsed"
++#define REG_DIR "/usr/java/packages"
++
++ {
++ /* sysclasspath, java_home, dll_dir */
++ {
++ char *home_path;
++ char *dll_path;
++ char *pslash;
++ char buf[MAXPATHLEN];
++ os::jvm_path(buf, sizeof(buf));
++
++ // Found the full path to libjvm.so.
++ // Now cut the path to <java_home>/jre if we can.
++ *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */
++ pslash = strrchr(buf, '/');
++ if (pslash != NULL)
++ *pslash = '\0'; /* get rid of /{client|server|hotspot} */
++ dll_path = malloc(strlen(buf) + 1);
++ if (dll_path == NULL)
++ return;
++ strcpy(dll_path, buf);
++ Arguments::set_dll_dir(dll_path);
++
++ if (pslash != NULL) {
++ pslash = strrchr(buf, '/');
++ if (pslash != NULL) {
++ *pslash = '\0'; /* get rid of /<arch> */
++ pslash = strrchr(buf, '/');
++ if (pslash != NULL)
++ *pslash = '\0'; /* get rid of /lib */
++ }
++ }
++
++ home_path = malloc(strlen(buf) + 1);
++ if (home_path == NULL)
++ return;
++ strcpy(home_path, buf);
++ Arguments::set_java_home(home_path);
++
++ if (!set_boot_path('/', ':'))
++ return;
++ }
++
++ /*
++ * Where to look for native libraries
++ *
++ * Note: Due to a legacy implementation, most of the library path
++ * is set in the launcher. This was to accomodate linking restrictions
++ * on legacy Bsd implementations (which are no longer supported).
++ * Eventually, all the library path setting will be done here.
++ *
++ * However, to prevent the proliferation of improperly built native
++ * libraries, the new path component /usr/java/packages is added here.
++ * Eventually, all the library path setting will be done here.
++ */
++ {
++ char *ld_library_path;
++
++ /*
++ * Construct the invariant part of ld_library_path. Note that the
++ * space for the colon and the trailing null are provided by the
++ * nulls included by the sizeof operator (so actually we allocate
++ * a byte more than necessary).
++ */
++ 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);
++
++ /*
++ * Get the user setting of LD_LIBRARY_PATH, and prepended it. It
++ * should always exist (until the legacy problem cited above is
++ * addressed).
++ */
++#ifdef __APPLE__
++ char *v = getenv("DYLD_LIBRARY_PATH");
++#else
++ char *v = getenv("LD_LIBRARY_PATH");
++#endif
++ if (v != NULL) {
++ char *t = ld_library_path;
++ /* 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);
++ }
++ Arguments::set_library_path(ld_library_path);
++ }
++
++ /*
++ * Extensions directories.
++ *
++ * Note that the space for the colon and the trailing null are provided
++ * by the nulls included by the sizeof operator (so actually one byte more
++ * than necessary is allocated).
++ */
++ {
++ 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());
++ Arguments::set_ext_dirs(buf);
++ }
++
++ /* Endorsed standards default directory. */
++ {
++ char * buf;
++ buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
++ sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
++ Arguments::set_endorsed_dirs(buf);
++ }
++ }
++
++#undef malloc
++#undef getenv
++#undef EXTENSIONS_DIR
++#undef ENDORSED_DIR
++
++ // Done
++ return;
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// breakpoint support
++
++void os::breakpoint() {
++ BREAKPOINT;
++}
++
++extern "C" void breakpoint() {
++ // use debugger to set breakpoint here
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// signal support
++
++debug_only(static bool signal_sets_initialized = false);
++static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
++
++bool os::Bsd::is_sig_ignored(int sig) {
++ struct sigaction oact;
++ sigaction(sig, (struct sigaction*)NULL, &oact);
++ void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction)
++ : CAST_FROM_FN_PTR(void*, oact.sa_handler);
++ if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
++ return true;
++ else
++ return false;
++}
++
++void os::Bsd::signal_sets_init() {
++ // Should also have an assertion stating we are still single-threaded.
++ assert(!signal_sets_initialized, "Already initialized");
++ // Fill in signals that are necessarily unblocked for all threads in
++ // the VM. Currently, we unblock the following signals:
++ // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
++ // by -Xrs (=ReduceSignalUsage));
++ // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
++ // other threads. The "ReduceSignalUsage" boolean tells us not to alter
++ // the dispositions or masks wrt these signals.
++ // Programs embedding the VM that want to use the above signals for their
++ // own purposes must, at this time, use the "-Xrs" option to prevent
++ // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
++ // (See bug 4345157, and other related bugs).
++ // In reality, though, unblocking these signals is really a nop, since
++ // these signals are not blocked by default.
++ sigemptyset(&unblocked_sigs);
++ sigemptyset(&allowdebug_blocked_sigs);
++ sigaddset(&unblocked_sigs, SIGILL);
++ sigaddset(&unblocked_sigs, SIGSEGV);
++ sigaddset(&unblocked_sigs, SIGBUS);
++ sigaddset(&unblocked_sigs, SIGFPE);
++ sigaddset(&unblocked_sigs, SR_signum);
++
++ if (!ReduceSignalUsage) {
++ if (!os::Bsd::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
++ sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
++ sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
++ }
++ if (!os::Bsd::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
++ sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
++ sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
++ }
++ if (!os::Bsd::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
++ sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
++ sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
++ }
++ }
++ // Fill in signals that are blocked by all but the VM thread.
++ sigemptyset(&vm_sigs);
++ if (!ReduceSignalUsage)
++ sigaddset(&vm_sigs, BREAK_SIGNAL);
++ debug_only(signal_sets_initialized = true);
++
++}
++
++// These are signals that are unblocked while a thread is running Java.
++// (For some reason, they get blocked by default.)
++sigset_t* os::Bsd::unblocked_signals() {
++ assert(signal_sets_initialized, "Not initialized");
++ return &unblocked_sigs;
++}
++
++// These are the signals that are blocked while a (non-VM) thread is
++// running Java. Only the VM thread handles these signals.
++sigset_t* os::Bsd::vm_signals() {
++ assert(signal_sets_initialized, "Not initialized");
++ return &vm_sigs;
++}
++
++// These are signals that are blocked during cond_wait to allow debugger in
++sigset_t* os::Bsd::allowdebug_blocked_signals() {
++ assert(signal_sets_initialized, "Not initialized");
++ return &allowdebug_blocked_sigs;
++}
++
++void os::Bsd::hotspot_sigmask(Thread* thread) {
++
++ //Save caller's signal mask before setting VM signal mask
++ sigset_t caller_sigmask;
++ pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);
++
++ OSThread* osthread = thread->osthread();
++ osthread->set_caller_sigmask(caller_sigmask);
++
++ pthread_sigmask(SIG_UNBLOCK, os::Bsd::unblocked_signals(), NULL);
++
++ if (!ReduceSignalUsage) {
++ if (thread->is_VM_thread()) {
++ // Only the VM thread handles BREAK_SIGNAL ...
++ pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);
++ } else {
++ // ... all other threads block BREAK_SIGNAL
++ pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);
++ }
++ }
++}
++
++#ifndef _ALLBSD_SOURCE
++//////////////////////////////////////////////////////////////////////////////
++// detecting pthread library
++
++void os::Bsd::libpthread_init() {
++ // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
++ // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
++ // generic name for earlier versions.
++ // Define macros here so we can build HotSpot on old systems.
++# ifndef _CS_GNU_LIBC_VERSION
++# define _CS_GNU_LIBC_VERSION 2
++# endif
++# ifndef _CS_GNU_LIBPTHREAD_VERSION
++# define _CS_GNU_LIBPTHREAD_VERSION 3
++# endif
++
++ size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
++ if (n > 0) {
++ char *str = (char *)malloc(n);
++ confstr(_CS_GNU_LIBC_VERSION, str, n);
++ os::Bsd::set_glibc_version(str);
++ } else {
++ // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
++ static char _gnu_libc_version[32];
++ jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
++ "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
++ os::Bsd::set_glibc_version(_gnu_libc_version);
++ }
++
++ n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
++ if (n > 0) {
++ char *str = (char *)malloc(n);
++ confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
++ // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
++ // us "NPTL-0.29" even we are running with BsdThreads. Check if this
++ // is the case. BsdThreads has a hard limit on max number of threads.
++ // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
++ // On the other hand, NPTL does not have such a limit, sysconf()
++ // will return -1 and errno is not changed. Check if it is really NPTL.
++ if (strcmp(os::Bsd::glibc_version(), "glibc 2.3.2") == 0 &&
++ strstr(str, "NPTL") &&
++ sysconf(_SC_THREAD_THREADS_MAX) > 0) {
++ free(str);
++ os::Bsd::set_libpthread_version("bsdthreads");
++ } else {
++ os::Bsd::set_libpthread_version(str);
++ }
++ } else {
++ // glibc before 2.3.2 only has BsdThreads.
++ os::Bsd::set_libpthread_version("bsdthreads");
++ }
++
++ if (strstr(libpthread_version(), "NPTL")) {
++ os::Bsd::set_is_NPTL();
++ } else {
++ os::Bsd::set_is_BsdThreads();
++ }
++
++ // BsdThreads have two flavors: floating-stack mode, which allows variable
++ // stack size; and fixed-stack mode. NPTL is always floating-stack.
++ if (os::Bsd::is_NPTL() || os::Bsd::supports_variable_stack_size()) {
++ os::Bsd::set_is_floating_stack();
++ }
++}
++
++/////////////////////////////////////////////////////////////////////////////
++// thread stack
++
++// Force Bsd kernel to expand current thread stack. If "bottom" is close
++// to the stack guard, caller should block all signals.
++//
++// MAP_GROWSDOWN:
++// A special mmap() flag that is used to implement thread stacks. It tells
++// kernel that the memory region should extend downwards when needed. This
++// allows early versions of BsdThreads to only mmap the first few pages
++// when creating a new thread. Bsd kernel will automatically expand thread
++// stack as needed (on page faults).
++//
++// However, because the memory region of a MAP_GROWSDOWN stack can grow on
++// demand, if a page fault happens outside an already mapped MAP_GROWSDOWN
++// region, it's hard to tell if the fault is due to a legitimate stack
++// access or because of reading/writing non-exist memory (e.g. buffer
++// overrun). As a rule, if the fault happens below current stack pointer,
++// Bsd kernel does not expand stack, instead a SIGSEGV is sent to the
++// application (see Bsd kernel fault.c).
++//
++// This Bsd feature can cause SIGSEGV when VM bangs thread stack for
++// stack overflow detection.
++//
++// Newer version of BsdThreads (since glibc-2.2, or, RH-7.x) and NPTL do
++// not use this flag. However, the stack of initial thread is not created
++// by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
++// unlikely) that user code can create a thread with MAP_GROWSDOWN stack
++// and then attach the thread to JVM.
++//
++// To get around the problem and allow stack banging on Bsd, we need to
++// manually expand thread stack after receiving the SIGSEGV.
++//
++// There are two ways to expand thread stack to address "bottom", we used
++// both of them in JVM before 1.5:
++// 1. adjust stack pointer first so that it is below "bottom", and then
++// touch "bottom"
++// 2. mmap() the page in question
++//
++// Now alternate signal stack is gone, it's harder to use 2. For instance,
++// if current sp is already near the lower end of page 101, and we need to
++// call mmap() to map page 100, it is possible that part of the mmap() frame
++// will be placed in page 100. When page 100 is mapped, it is zero-filled.
++// That will destroy the mmap() frame and cause VM to crash.
++//
++// The following code works by adjusting sp first, then accessing the "bottom"
++// page to force a page fault. Bsd kernel will then automatically expand the
++// stack mapping.
++//
++// _expand_stack_to() assumes its frame size is less than page size, which
++// should always be true if the function is not inlined.
++
++#if __GNUC__ < 3 // gcc 2.x does not support noinline attribute
++#define NOINLINE
++#else
++#define NOINLINE __attribute__ ((noinline))
++#endif
++
++static void _expand_stack_to(address bottom) NOINLINE;
++
++static void _expand_stack_to(address bottom) {
++ address sp;
++ size_t size;
++ volatile char *p;
++
++ // Adjust bottom to point to the largest address within the same page, it
++ // gives us a one-page buffer if alloca() allocates slightly more memory.
++ bottom = (address)align_size_down((uintptr_t)bottom, os::Bsd::page_size());
++ bottom += os::Bsd::page_size() - 1;
++
++ // sp might be slightly above current stack pointer; if that's the case, we
++ // will alloca() a little more space than necessary, which is OK. Don't use
++ // os::current_stack_pointer(), as its result can be slightly below current
++ // stack pointer, causing us to not alloca enough to reach "bottom".
++ sp = (address)&sp;
++
++ if (sp > bottom) {
++ size = sp - bottom;
++ p = (volatile char *)alloca(size);
++ assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
++ p[0] = '\0';
++ }
++}
++
++bool os::Bsd::manually_expand_stack(JavaThread * t, address addr) {
++ assert(t!=NULL, "just checking");
++ assert(t->osthread()->expanding_stack(), "expand should be set");
++ assert(t->stack_base() != NULL, "stack_base was not initialized");
++
++ if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) {
++ sigset_t mask_all, old_sigset;
++ sigfillset(&mask_all);
++ pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
++ _expand_stack_to(addr);
++ pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
++ return true;
++ }
++ return false;
++}
++#endif
++
++//////////////////////////////////////////////////////////////////////////////
++// create new thread
++
++static address highest_vm_reserved_address();
++
++// check if it's safe to start a new thread
++static bool _thread_safety_check(Thread* thread) {
++#ifdef _ALLBSD_SOURCE
++ return true;
++#else
++ if (os::Bsd::is_BsdThreads() && !os::Bsd::is_floating_stack()) {
++ // Fixed stack BsdThreads (SuSE Bsd/x86, and some versions of Redhat)
++ // Heap is mmap'ed at lower end of memory space. Thread stacks are
++ // allocated (MAP_FIXED) from high address space. Every thread stack
++ // occupies a fixed size slot (usually 2Mbytes, but user can change
++ // it to other values if they rebuild BsdThreads).
++ //
++ // Problem with MAP_FIXED is that mmap() can still succeed even part of
++ // the memory region has already been mmap'ed. That means if we have too
++ // many threads and/or very large heap, eventually thread stack will
++ // collide with heap.
++ //
++ // Here we try to prevent heap/stack collision by comparing current
++ // stack bottom with the highest address that has been mmap'ed by JVM
++ // plus a safety margin for memory maps created by native code.
++ //
++ // This feature can be disabled by setting ThreadSafetyMargin to 0
++ //
++ if (ThreadSafetyMargin > 0) {
++ address stack_bottom = os::current_stack_base() - os::current_stack_size();
++
++ // not safe if our stack extends below the safety margin
++ return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
++ } else {
++ return true;
++ }
++ } else {
++ // Floating stack BsdThreads or NPTL:
++ // Unlike fixed stack BsdThreads, thread stacks are not MAP_FIXED. When
++ // there's not enough space left, pthread_create() will fail. If we come
++ // here, that means enough space has been reserved for stack.
++ return true;
++ }
++#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.
++ // This helps when threads of the same stack traces evict each other's
++ // cache lines. The threads can be either from the same JVM instance, or
++ // from different JVM instances. The benefit is especially true for
++ // processors with hyperthreading technology.
++ static int counter = 0;
++ int pid = os::current_process_id();
++ alloca(((pid ^ counter++) & 7) * 128);
++
++ ThreadLocalStorage::set_thread(thread);
++
++ OSThread* osthread = thread->osthread();
++ Monitor* sync = osthread->startThread_lock();
++
++ // non floating stack BsdThreads needs extra check, see above
++ if (!_thread_safety_check(thread)) {
++ // notify parent thread
++ MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
++ osthread->set_state(ZOMBIE);
++ sync->notify_all();
++ return NULL;
++ }
++
++#ifdef _ALLBSD_SOURCE
++ // thread_id is pthread_id on BSD
++ osthread->set_thread_id(::pthread_self());
++#else
++ // thread_id is kernel thread id (similar to Solaris LWP id)
++ osthread->set_thread_id(os::Bsd::gettid());
++
++ if (UseNUMA) {
++ int lgrp_id = os::numa_get_group_id();
++ if (lgrp_id != -1) {
++ thread->set_lgrp_id(lgrp_id);
++ }
++ }
++#endif
++ // initialize signal mask for this thread
++ os::Bsd::hotspot_sigmask(thread);
++
++ // initialize floating point control register
++ os::Bsd::init_thread_fpu_state();
++
++ // handshaking with parent thread
++ {
++ MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
++
++ // notify parent thread
++ osthread->set_state(INITIALIZED);
++ sync->notify_all();
++
++ // wait until os::start_thread()
++ while (osthread->get_state() == INITIALIZED) {
++ sync->wait(Mutex::_no_safepoint_check_flag);
++ }
++ }
++
++ // call one more level start routine
++ thread->run();
++
++ return 0;
++}
++
++bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
++ assert(thread->osthread() == NULL, "caller responsible");
++
++ // Allocate the OSThread object
++ OSThread* osthread = new OSThread(NULL, NULL);
++ if (osthread == NULL) {
++ return false;
++ }
++
++ // set the correct thread state
++ osthread->set_thread_type(thr_type);
++
++ // Initial state is ALLOCATED but not INITIALIZED
++ osthread->set_state(ALLOCATED);
++
++ thread->set_osthread(osthread);
++
++ // init thread attributes
++ pthread_attr_t attr;
++ pthread_attr_init(&attr);
++ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
++
++ // stack size
++ if (os::Bsd::supports_variable_stack_size()) {
++ // calculate stack size if it's not specified by caller
++ if (stack_size == 0) {
++ stack_size = os::Bsd::default_stack_size(thr_type);
++
++ switch (thr_type) {
++ case os::java_thread:
++ // Java threads use ThreadStackSize which default value can be
++ // changed with the flag -Xss
++ assert (JavaThread::stack_size_at_create() > 0, "this should be set");
++ stack_size = JavaThread::stack_size_at_create();
++ break;
++ case os::compiler_thread:
++ if (CompilerThreadStackSize > 0) {
++ stack_size = (size_t)(CompilerThreadStackSize * K);
++ break;
++ } // else fall through:
++ // use VMThreadStackSize if CompilerThreadStackSize is not defined
++ case os::vm_thread:
++ case os::pgc_thread:
++ case os::cgc_thread:
++ case os::watcher_thread:
++ if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
++ break;
++ }
++ }
++
++ stack_size = MAX2(stack_size, os::Bsd::min_stack_allowed);
++ pthread_attr_setstacksize(&attr, stack_size);
++ } else {
++ // let pthread_create() pick the default value.
++ }
++
++#ifndef _ALLBSD_SOURCE
++ // glibc guard page
++ pthread_attr_setguardsize(&attr, os::Bsd::default_guard_size(thr_type));
++#endif
++
++ ThreadState state;
++
++ {
++
++#ifndef _ALLBSD_SOURCE
++ // Serialize thread creation if we are running with fixed stack BsdThreads
++ bool lock = os::Bsd::is_BsdThreads() && !os::Bsd::is_floating_stack();
++ if (lock) {
++ os::Bsd::createThread_lock()->lock_without_safepoint_check();
++ }
++#endif
++
++ pthread_t tid;
++ int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
++
++ pthread_attr_destroy(&attr);
++
++ if (ret != 0) {
++ if (PrintMiscellaneous && (Verbose || WizardMode)) {
++ perror("pthread_create()");
++ }
++ // Need to clean up stuff we've allocated so far
++ thread->set_osthread(NULL);
++ delete osthread;
++#ifndef _ALLBSD_SOURCE
++ if (lock) os::Bsd::createThread_lock()->unlock();
++#endif
++ return false;
++ }
++
++ // Store pthread info into the OSThread
++ osthread->set_pthread_id(tid);
++
++ // Wait until child thread is either initialized or aborted
++ {
++ Monitor* sync_with_child = osthread->startThread_lock();
++ MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
++ while ((state = osthread->get_state()) == ALLOCATED) {
++ sync_with_child->wait(Mutex::_no_safepoint_check_flag);
++ }
++ }
++
++#ifndef _ALLBSD_SOURCE
++ if (lock) {
++ os::Bsd::createThread_lock()->unlock();
++ }
++#endif
++ }
++
++ // Aborted due to thread limit being reached
++ if (state == ZOMBIE) {
++ thread->set_osthread(NULL);
++ delete osthread;
++ return false;
++ }
++
++ // The thread is returned suspended (in state INITIALIZED),
++ // and is started higher up in the call chain
++ assert(state == INITIALIZED, "race condition");
++ return true;
++}
++
++/////////////////////////////////////////////////////////////////////////////
++// attach existing thread
++
++// bootstrap the main thread
++bool os::create_main_thread(JavaThread* thread) {
++ assert(os::Bsd::_main_thread == pthread_self(), "should be called inside main thread");
++ return create_attached_thread(thread);
++}
++
++bool os::create_attached_thread(JavaThread* thread) {
++#ifdef ASSERT
++ thread->verify_not_published();
++#endif
++
++ // Allocate the OSThread object
++ OSThread* osthread = new OSThread(NULL, NULL);
++
++ if (osthread == NULL) {
++ return false;
++ }
++
++ // Store pthread info into the OSThread
++#ifdef _ALLBSD_SOURCE
++ osthread->set_thread_id(::pthread_self());
++#else
++ osthread->set_thread_id(os::Bsd::gettid());
++#endif
++ osthread->set_pthread_id(::pthread_self());
++
++ // initialize floating point control register
++ os::Bsd::init_thread_fpu_state();
++
++ // Initial thread state is RUNNABLE
++ osthread->set_state(RUNNABLE);
++
++ thread->set_osthread(osthread);
++
++#ifndef _ALLBSD_SOURCE
++ if (UseNUMA) {
++ int lgrp_id = os::numa_get_group_id();
++ if (lgrp_id != -1) {
++ thread->set_lgrp_id(lgrp_id);
++ }
++ }
++
++ if (os::Bsd::is_initial_thread()) {
++ // If current thread is initial thread, its stack is mapped on demand,
++ // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
++ // the entire stack region to avoid SEGV in stack banging.
++ // It is also useful to get around the heap-stack-gap problem on SuSE
++ // kernel (see 4821821 for details). We first expand stack to the top
++ // of yellow zone, then enable stack yellow zone (order is significant,
++ // enabling yellow zone first will crash JVM on SuSE Bsd), so there
++ // is no gap between the last two virtual memory regions.
++
++ JavaThread *jt = (JavaThread *)thread;
++ address addr = jt->stack_yellow_zone_base();
++ assert(addr != NULL, "initialization problem?");
++ assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
++
++ osthread->set_expanding_stack();
++ os::Bsd::manually_expand_stack(jt, addr);
++ osthread->clear_expanding_stack();
++ }
++#endif
++
++ // initialize signal mask for this thread
++ // and save the caller's signal mask
++ os::Bsd::hotspot_sigmask(thread);
++
++ return true;
++}
++
++void os::pd_start_thread(Thread* thread) {
++ OSThread * osthread = thread->osthread();
++ assert(osthread->get_state() != INITIALIZED, "just checking");
++ Monitor* sync_with_child = osthread->startThread_lock();
++ MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
++ sync_with_child->notify();
++}
++
++// Free Bsd resources related to the OSThread
++void os::free_thread(OSThread* osthread) {
++ assert(osthread != NULL, "osthread not set");
++
++ if (Thread::current()->osthread() == osthread) {
++ // Restore caller's signal mask
++ sigset_t sigmask = osthread->caller_sigmask();
++ pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
++ }
++
++ delete osthread;
++}
++
++//////////////////////////////////////////////////////////////////////////////
++// thread local storage
++
++int os::allocate_thread_local_storage() {
++ pthread_key_t key;
++ int rslt = pthread_key_create(&key, NULL);
++ assert(rslt == 0, "cannot allocate thread local storage");
++ return (int)key;
++}
++
++// Note: This is currently not used by VM, as we don't destroy TLS key
++// on VM exit.
++void os::free_thread_local_storage(int index) {
++ int rslt = pthread_key_delete((pthread_key_t)index);
++ assert(rslt == 0, "invalid index");
++}
++
++void os::thread_local_storage_at_put(int index, void* value) {
++ int rslt = pthread_setspecific((pthread_key_t)index, value);
++ assert(rslt == 0, "pthread_setspecific failed");
++}
++
++extern "C" Thread* get_thread() {
++ return ThreadLocalStorage::thread();
++}
++
++//////////////////////////////////////////////////////////////////////////////
++// initial thread
++
++#ifndef _ALLBSD_SOURCE
++// Check if current thread is the initial thread, similar to Solaris thr_main.
++bool os::Bsd::is_initial_thread(void) {
++ char dummy;
++ // If called before init complete, thread stack bottom will be null.
++ // Can be called if fatal error occurs before initialization.
++ if (initial_thread_stack_bottom() == NULL) return false;
++ assert(initial_thread_stack_bottom() != NULL &&
++ initial_thread_stack_size() != 0,
++ "os::init did not locate initial thread's stack region");
++ if ((address)&dummy >= initial_thread_stack_bottom() &&
++ (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size())
++ return true;
++ else return false;
++}
++
++// Find the virtual memory area that contains addr
++static bool find_vma(address addr, address* vma_low, address* vma_high) {
++ FILE *fp = fopen("/proc/self/maps", "r");
++ if (fp) {
++ address low, high;
++ while (!feof(fp)) {
++ if (fscanf(fp, "%p-%p", &low, &high) == 2) {
++ if (low <= addr && addr < high) {
++ if (vma_low) *vma_low = low;
++ if (vma_high) *vma_high = high;
++ fclose (fp);
++ return true;
++ }
++ }
++ for (;;) {
++ int ch = fgetc(fp);
++ if (ch == EOF || ch == (int)'\n') break;
++ }
++ }
++ fclose(fp);
++ }
++ return false;
++}
++
++// Locate initial thread stack. This special handling of initial thread stack
++// is needed because pthread_getattr_np() on most (all?) Bsd distros returns
++// bogus value for initial thread.
++void os::Bsd::capture_initial_stack(size_t max_size) {
++ // stack size is the easy part, get it from RLIMIT_STACK
++ size_t stack_size;
++ struct rlimit rlim;
++ getrlimit(RLIMIT_STACK, &rlim);
++ stack_size = rlim.rlim_cur;
++
++ // 6308388: a bug in ld.so will relocate its own .data section to the
++ // lower end of primordial stack; reduce ulimit -s value a little bit
++ // so we won't install guard page on ld.so's data section.
++ stack_size -= 2 * page_size();
++
++ // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
++ // 7.1, in both cases we will get 2G in return value.
++ // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
++ // SuSE 7.2, Debian) can not handle alternate signal stack correctly
++ // for initial thread if its stack size exceeds 6M. Cap it at 2M,
++ // in case other parts in glibc still assumes 2M max stack size.
++ // FIXME: alt signal stack is gone, maybe we can relax this constraint?
++#ifndef IA64
++ if (stack_size > 2 * K * K) stack_size = 2 * K * K;
++#else
++ // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
++ if (stack_size > 4 * K * K) stack_size = 4 * K * K;
++#endif
++
++ // Try to figure out where the stack base (top) is. This is harder.
++ //
++ // When an application is started, glibc saves the initial stack pointer in
++ // a global variable "__libc_stack_end", which is then used by system
++ // libraries. __libc_stack_end should be pretty close to stack top. The
++ // variable is available since the very early days. However, because it is
++ // a private interface, it could disappear in the future.
++ //
++ // Bsd kernel saves start_stack information in /proc/<pid>/stat. Similar
++ // to __libc_stack_end, it is very close to stack top, but isn't the real
++ // stack top. Note that /proc may not exist if VM is running as a chroot
++ // program, so reading /proc/<pid>/stat could fail. Also the contents of
++ // /proc/<pid>/stat could change in the future (though unlikely).
++ //
++ // We try __libc_stack_end first. If that doesn't work, look for
++ // /proc/<pid>/stat. If neither of them works, we use current stack pointer
++ // as a hint, which should work well in most cases.
++
++ uintptr_t stack_start;
++
++ // try __libc_stack_end first
++ uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end");
++ if (p && *p) {
++ stack_start = *p;
++ } else {
++ // see if we can get the start_stack field from /proc/self/stat
++ FILE *fp;
++ int pid;
++ char state;
++ int ppid;
++ int pgrp;
++ int session;
++ int nr;
++ int tpgrp;
++ unsigned long flags;
++ unsigned long minflt;
++ unsigned long cminflt;
++ unsigned long majflt;
++ unsigned long cmajflt;
++ unsigned long utime;
++ unsigned long stime;
++ long cutime;
++ long cstime;
++ long prio;
++ long nice;
++ long junk;
++ long it_real;
++ uintptr_t start;
++ uintptr_t vsize;
++ intptr_t rss;
++ uintptr_t rsslim;
++ uintptr_t scodes;
++ uintptr_t ecode;
++ int i;
++
++ // Figure what the primordial thread stack base is. Code is inspired
++ // by email from Hans Boehm. /proc/self/stat begins with current pid,
++ // followed by command name surrounded by parentheses, state, etc.
++ char stat[2048];
++ int statlen;
++
++ fp = fopen("/proc/self/stat", "r");
++ if (fp) {
++ statlen = fread(stat, 1, 2047, fp);
++ stat[statlen] = '\0';
++ fclose(fp);
++
++ // Skip pid and the command string. Note that we could be dealing with
++ // weird command names, e.g. user could decide to rename java launcher
++ // to "java 1.4.2 :)", then the stat file would look like
++ // 1234 (java 1.4.2 :)) R ... ...
++ // We don't really need to know the command string, just find the last
++ // occurrence of ")" and then start parsing from there. See bug 4726580.
++ char * s = strrchr(stat, ')');
++
++ i = 0;
++ if (s) {
++ // Skip blank chars
++ do s++; while (isspace(*s));
++
++#define _UFM UINTX_FORMAT
++#define _DFM INTX_FORMAT
++
++ /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */
++ /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */
++ i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
++ &state, /* 3 %c */
++ &ppid, /* 4 %d */
++ &pgrp, /* 5 %d */
++ &session, /* 6 %d */
++ &nr, /* 7 %d */
++ &tpgrp, /* 8 %d */
++ &flags, /* 9 %lu */
++ &minflt, /* 10 %lu */
++ &cminflt, /* 11 %lu */
++ &majflt, /* 12 %lu */
++ &cmajflt, /* 13 %lu */
++ &utime, /* 14 %lu */
++ &stime, /* 15 %lu */
++ &cutime, /* 16 %ld */
++ &cstime, /* 17 %ld */
++ &prio, /* 18 %ld */
++ &nice, /* 19 %ld */
++ &junk, /* 20 %ld */
++ &it_real, /* 21 %ld */
++ &start, /* 22 UINTX_FORMAT */
++ &vsize, /* 23 UINTX_FORMAT */
++ &rss, /* 24 INTX_FORMAT */
++ &rsslim, /* 25 UINTX_FORMAT */
++ &scodes, /* 26 UINTX_FORMAT */
++ &ecode, /* 27 UINTX_FORMAT */
++ &stack_start); /* 28 UINTX_FORMAT */
++ }
++
++#undef _UFM
++#undef _DFM
++
++ if (i != 28 - 2) {
++ assert(false, "Bad conversion from /proc/self/stat");
++ // product mode - assume we are the initial thread, good luck in the
++ // embedded case.
++ warning("Can't detect initial thread stack location - bad conversion");
++ stack_start = (uintptr_t) &rlim;
++ }
++ } else {
++ // For some reason we can't open /proc/self/stat (for example, running on
++ // FreeBSD with a Bsd emulator, or inside chroot), this should work for
++ // most cases, so don't abort:
++ warning("Can't detect initial thread stack location - no /proc/self/stat");
++ stack_start = (uintptr_t) &rlim;
++ }
++ }
++
++ // Now we have a pointer (stack_start) very close to the stack top, the
++ // next thing to do is to figure out the exact location of stack top. We
++ // can find out the virtual memory area that contains stack_start by
++ // reading /proc/self/maps, it should be the last vma in /proc/self/maps,
++ // and its upper limit is the real stack top. (again, this would fail if
++ // running inside chroot, because /proc may not exist.)
++
++ uintptr_t stack_top;
++ address low, high;
++ if (find_vma((address)stack_start, &low, &high)) {
++ // success, "high" is the true stack top. (ignore "low", because initial
++ // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.)
++ stack_top = (uintptr_t)high;
++ } else {
++ // failed, likely because /proc/self/maps does not exist
++ warning("Can't detect initial thread stack location - find_vma failed");
++ // best effort: stack_start is normally within a few pages below the real
++ // stack top, use it as stack top, and reduce stack size so we won't put
++ // guard page outside stack.
++ stack_top = stack_start;
++ stack_size -= 16 * page_size();
++ }
++
++ // stack_top could be partially down the page so align it
++ stack_top = align_size_up(stack_top, page_size());
++
++ if (max_size && stack_size > max_size) {
++ _initial_thread_stack_size = max_size;
++ } else {
++ _initial_thread_stack_size = stack_size;
++ }
++
++ _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
++ _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
++}
++#endif
++
++////////////////////////////////////////////////////////////////////////////////
++// time support
++
++// Time since start-up in seconds to a fine granularity.
++// Used by VMSelfDestructTimer and the MemProfiler.
++double os::elapsedTime() {
++
++ return (double)(os::elapsed_counter()) * 0.000001;
++}
++
++jlong os::elapsed_counter() {
++ timeval time;
++ int status = gettimeofday(&time, NULL);
++ return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
++}
++
++jlong os::elapsed_frequency() {
++ return (1000 * 1000);
++}
++
++// XXX: For now, code this as if BSD does not support vtime.
++bool os::supports_vtime() { return false; }
++bool os::enable_vtime() { return false; }
++bool os::vtime_enabled() { return false; }
++double os::elapsedVTime() {
++ // better than nothing, but not much
++ return elapsedTime();
++}
++
++jlong os::javaTimeMillis() {
++ timeval time;
++ int status = gettimeofday(&time, NULL);
++ assert(status != -1, "bsd error");
++ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
++}
++
++#ifndef CLOCK_MONOTONIC
++#define CLOCK_MONOTONIC (1)
++#endif
++
++#ifdef __APPLE__
++void os::Bsd::clock_init() {
++ // XXXDARWIN: Investigate replacement monotonic clock
++}
++#elif defined(_ALLBSD_SOURCE)
++void os::Bsd::clock_init() {
++ struct timespec res;
++ struct timespec tp;
++ if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 &&
++ ::clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
++ // yes, monotonic clock is supported
++ _clock_gettime = ::clock_gettime;
++ }
++}
++#else
++void os::Bsd::clock_init() {
++ // we do dlopen's in this particular order due to bug in bsd
++ // dynamical loader (see 6348968) leading to crash on exit
++ void* handle = dlopen("librt.so.1", RTLD_LAZY);
++ if (handle == NULL) {
++ handle = dlopen("librt.so", RTLD_LAZY);
++ }
++
++ if (handle) {
++ int (*clock_getres_func)(clockid_t, struct timespec*) =
++ (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
++ int (*clock_gettime_func)(clockid_t, struct timespec*) =
++ (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
++ if (clock_getres_func && clock_gettime_func) {
++ // See if monotonic clock is supported by the kernel. Note that some
++ // early implementations simply return kernel jiffies (updated every
++ // 1/100 or 1/1000 second). It would be bad to use such a low res clock
++ // for nano time (though the monotonic property is still nice to have).
++ // It's fixed in newer kernels, however clock_getres() still returns
++ // 1/HZ. We check if clock_getres() works, but will ignore its reported
++ // resolution for now. Hopefully as people move to new kernels, this
++ // won't be a problem.
++ struct timespec res;
++ struct timespec tp;
++ if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
++ clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
++ // yes, monotonic clock is supported
++ _clock_gettime = clock_gettime_func;
++ } else {
++ // close librt if there is no monotonic clock
++ dlclose(handle);
++ }
++ }
++ }
++}
++#endif
++
++#ifndef _ALLBSD_SOURCE
++#ifndef SYS_clock_getres
++
++#if defined(IA32) || defined(AMD64)
++#define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229)
++#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
++#else
++#warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
++#define sys_clock_getres(x,y) -1
++#endif
++
++#else
++#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
++#endif
++
++void os::Bsd::fast_thread_clock_init() {
++ if (!UseBsdPosixThreadCPUClocks) {
++ return;
++ }
++ clockid_t clockid;
++ struct timespec tp;
++ int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
++ (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
++
++ // Switch to using fast clocks for thread cpu time if
++ // the sys_clock_getres() returns 0 error code.
++ // Note, that some kernels may support the current thread
++ // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
++ // returned by the pthread_getcpuclockid().
++ // If the fast Posix clocks are supported then the sys_clock_getres()
++ // must return at least tp.tv_sec == 0 which means a resolution
++ // better than 1 sec. This is extra check for reliability.
++
++ if(pthread_getcpuclockid_func &&
++ pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
++ sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
++
++ _supports_fast_thread_cpu_time = true;
++ _pthread_getcpuclockid = pthread_getcpuclockid_func;
++ }
++}
++#endif
++
++jlong os::javaTimeNanos() {
++ if (Bsd::supports_monotonic_clock()) {
++ struct timespec tp;
++ int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp);
++ assert(status == 0, "gettime error");
++ jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
++ return result;
++ } else {
++ timeval time;
++ int status = gettimeofday(&time, NULL);
++ assert(status != -1, "bsd error");
++ jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
++ return 1000 * usecs;
++ }
++}
++
++void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
++ if (Bsd::supports_monotonic_clock()) {
++ info_ptr->max_value = ALL_64_BITS;
++
++ // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
++ info_ptr->may_skip_backward = false; // not subject to resetting or drifting
++ info_ptr->may_skip_forward = false; // not subject to resetting or drifting
++ } else {
++ // gettimeofday - based on time in seconds since the Epoch thus does not wrap
++ info_ptr->max_value = ALL_64_BITS;
++
++ // gettimeofday is a real time clock so it skips
++ info_ptr->may_skip_backward = true;
++ info_ptr->may_skip_forward = true;
++ }
++
++ info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
++}
++
++// Return the real, user, and system times in seconds from an
++// arbitrary fixed point in the past.
++bool os::getTimesSecs(double* process_real_time,
++ double* process_user_time,
++ double* process_system_time) {
++ struct tms ticks;
++ clock_t real_ticks = times(&ticks);
++
++ if (real_ticks == (clock_t) (-1)) {
++ return false;
++ } else {
++ double ticks_per_second = (double) clock_tics_per_sec;
++ *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
++ *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
++ *process_real_time = ((double) real_ticks) / ticks_per_second;
++
++ return true;
++ }
++}
++
++
++char * os::local_time_string(char *buf, size_t buflen) {
++ struct tm t;
++ time_t long_time;
++ time(&long_time);
++ localtime_r(&long_time, &t);
++ jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
++ t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
++ t.tm_hour, t.tm_min, t.tm_sec);
++ return buf;
++}
++
++struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
++ return localtime_r(clock, res);
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// runtime exit support
++
++// Note: os::shutdown() might be called very early during initialization, or
++// called from signal handler. Before adding something to os::shutdown(), make
++// sure it is async-safe and can handle partially initialized VM.
++void os::shutdown() {
++
++ // allow PerfMemory to attempt cleanup of any persistent resources
++ perfMemory_exit();
++
++ // needs to remove object in file system
++ AttachListener::abort();
++
++ // flush buffered output, finish log files
++ ostream_abort();
++
++ // Check for abort hook
++ abort_hook_t abort_hook = Arguments::abort_hook();
++ if (abort_hook != NULL) {
++ abort_hook();
++ }
++
++}
++
++// Note: os::abort() might be called very early during initialization, or
++// called from signal handler. Before adding something to os::abort(), make
++// sure it is async-safe and can handle partially initialized VM.
++void os::abort(bool dump_core) {
++ os::shutdown();
++ if (dump_core) {
++#ifndef PRODUCT
++ fdStream out(defaultStream::output_fd());
++ out.print_raw("Current thread is ");
++ char buf[16];
++ jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
++ out.print_raw_cr(buf);
++ out.print_raw_cr("Dumping core ...");
++#endif
++ ::abort(); // dump core
++ }
++
++ ::exit(1);
++}
++
++// Die immediately, no exit hook, no abort hook, no cleanup.
++void os::die() {
++ // _exit() on BsdThreads only kills current thread
++ ::abort();
++}
++
++// unused on bsd for now.
++void os::set_error_file(const char *logfile) {}
++
++
++// This method is a copy of JDK's sysGetLastErrorString
++// from src/solaris/hpi/src/system_md.c
++
++size_t os::lasterror(char *buf, size_t len) {
++
++ if (errno == 0) return 0;
++
++ const char *s = ::strerror(errno);
++ size_t n = ::strlen(s);
++ if (n >= len) {
++ n = len - 1;
++ }
++ ::strncpy(buf, s, n);
++ buf[n] = '\0';
++ return n;
++}
++
++intx os::current_thread_id() { return (intx)pthread_self(); }
++int os::current_process_id() {
++
++ // Under the old bsd thread library, bsd gives each thread
++ // its own process id. Because of this each thread will return
++ // a different pid if this method were to return the result
++ // of getpid(2). Bsd provides no api that returns the pid
++ // of the launcher thread for the vm. This implementation
++ // returns a unique pid, the pid of the launcher thread
++ // that starts the vm 'process'.
++
++ // Under the NPTL, getpid() returns the same pid as the
++ // launcher thread rather than a unique pid per thread.
++ // Use gettid() if you want the old pre NPTL behaviour.
++
++ // if you are looking for the result of a call to getpid() that
++ // returns a unique pid for the calling thread, then look at the
++ // OSThread::thread_id() method in osThread_bsd.hpp file
++
++ return (int)(_initial_pid ? _initial_pid : getpid());
++}
++
++// DLL functions
++
++#define JNI_LIB_PREFIX "lib"
++#ifdef __APPLE__
++#define JNI_LIB_SUFFIX ".dylib"
++#else
++#define JNI_LIB_SUFFIX ".so"
++#endif
++
++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.
++const char* os::get_temp_directory() { return "/tmp"; }
++
++static bool file_exists(const char* filename) {
++ struct stat statbuf;
++ if (filename == NULL || strlen(filename) == 0) {
++ return false;
++ }
++ return os::stat(filename, &statbuf) == 0;
++}
++
++void os::dll_build_name(char* buffer, size_t buflen,
++ const char* pname, const char* fname) {
++ // Copied from libhpi
++ const size_t pnamelen = pname ? strlen(pname) : 0;
++
++ // Quietly truncate on buffer overflow. Should be an error.
++ if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) {
++ *buffer = '\0';
++ return;
++ }
++
++ if (pnamelen == 0) {
++ snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname);
++ } else if (strchr(pname, *os::path_separator()) != NULL) {
++ int n;
++ char** pelements = split_path(pname, &n);
++ for (int i = 0 ; i < n ; i++) {
++ // Really shouldn't be NULL, but check can't hurt
++ if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
++ continue; // skip the empty path values
++ }
++ snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX,
++ pelements[i], fname);
++ if (file_exists(buffer)) {
++ break;
++ }
++ }
++ // release the storage
++ for (int i = 0 ; i < n ; i++) {
++ if (pelements[i] != NULL) {
++ FREE_C_HEAP_ARRAY(char, pelements[i]);
++ }
++ }
++ if (pelements != NULL) {
++ FREE_C_HEAP_ARRAY(char*, pelements);
++ }
++ } else {
++ snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
++ }
++}
++
++const char* os::get_current_directory(char *buf, int buflen) {
++ return getcwd(buf, buflen);
++}
++
++// check if addr is inside libjvm[_g].so
++bool os::address_is_in_vm(address addr) {
++ static address libjvm_base_addr;
++ Dl_info dlinfo;
++
++ if (libjvm_base_addr == NULL) {
++ dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
++ libjvm_base_addr = (address)dlinfo.dli_fbase;
++ assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
++ }
++
++ if (dladdr((void *)addr, &dlinfo)) {
++ if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
++ }
++
++ return false;
++}
++
++bool os::dll_address_to_function_name(address addr, char *buf,
++ int buflen, int *offset) {
++ Dl_info dlinfo;
++
++ if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
++ if (buf != NULL) {
++ if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
++ jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
++ }
++ }
++ if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
++ return true;
++ } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
++ if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
++ dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
++ return true;
++ }
++ }
++
++ if (buf != NULL) buf[0] = '\0';
++ if (offset != NULL) *offset = -1;
++ return false;
++}
++
++#ifdef _ALLBSD_SOURCE
++// ported from solaris version
++bool os::dll_address_to_library_name(address addr, char* buf,
++ int buflen, int* offset) {
++ Dl_info dlinfo;
++
++ if (dladdr((void*)addr, &dlinfo)){
++ if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
++ if (offset) *offset = addr - (address)dlinfo.dli_fbase;
++ return true;
++ } else {
++ if (buf) buf[0] = '\0';
++ if (offset) *offset = -1;
++ return false;
++ }
++}
++#else
++struct _address_to_library_name {
++ address addr; // input : memory address
++ size_t buflen; // size of fname
++ char* fname; // output: library name
++ address base; // library base addr
++};
++
++static int address_to_library_name_callback(struct dl_phdr_info *info,
++ size_t size, void *data) {
++ int i;
++ bool found = false;
++ address libbase = NULL;
++ struct _address_to_library_name * d = (struct _address_to_library_name *)data;
++
++ // iterate through all loadable segments
++ for (i = 0; i < info->dlpi_phnum; i++) {
++ address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
++ if (info->dlpi_phdr[i].p_type == PT_LOAD) {
++ // base address of a library is the lowest address of its loaded
++ // segments.
++ if (libbase == NULL || libbase > segbase) {
++ libbase = segbase;
++ }
++ // see if 'addr' is within current segment
++ if (segbase <= d->addr &&
++ d->addr < segbase + info->dlpi_phdr[i].p_memsz) {
++ found = true;
++ }
++ }
++ }
++
++ // dlpi_name is NULL or empty if the ELF file is executable, return 0
++ // so dll_address_to_library_name() can fall through to use dladdr() which
++ // can figure out executable name from argv[0].
++ if (found && info->dlpi_name && info->dlpi_name[0]) {
++ d->base = libbase;
++ if (d->fname) {
++ jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name);
++ }
++ return 1;
++ }
++ return 0;
++}
++
++bool os::dll_address_to_library_name(address addr, char* buf,
++ int buflen, int* offset) {
++ Dl_info dlinfo;
++ struct _address_to_library_name data;
++
++ // There is a bug in old glibc dladdr() implementation that it could resolve
++ // to wrong library name if the .so file has a base address != NULL. Here
++ // we iterate through the program headers of all loaded libraries to find
++ // out which library 'addr' really belongs to. This workaround can be
++ // removed once the minimum requirement for glibc is moved to 2.3.x.
++ data.addr = addr;
++ data.fname = buf;
++ data.buflen = buflen;
++ data.base = NULL;
++ int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data);
++
++ if (rslt) {
++ // buf already contains library name
++ if (offset) *offset = addr - data.base;
++ return true;
++ } else if (dladdr((void*)addr, &dlinfo)){
++ if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
++ if (offset) *offset = addr - (address)dlinfo.dli_fbase;
++ return true;
++ } else {
++ if (buf) buf[0] = '\0';
++ if (offset) *offset = -1;
++ return false;
++ }
++}
++#endif
++
++ // Loads .dll/.so and
++ // in case of error it checks if .dll/.so was built for the
++ // same architecture as Hotspot is running on
++
++#ifdef __APPLE__
++void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
++ void * result= ::dlopen(filename, RTLD_LAZY);
++ if (result != NULL) {
++ // Successful loading
++ return result;
++ }
++
++ // Read system error message into ebuf
++ ::strncpy(ebuf, ::dlerror(), ebuflen-1);
++ ebuf[ebuflen-1]='\0';
++
++ return NULL;
++}
++#else
++void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
++{
++ void * result= ::dlopen(filename, RTLD_LAZY);
++ if (result != NULL) {
++ // Successful loading
++ return result;
++ }
++
++ Elf32_Ehdr elf_head;
++
++ // Read system error message into ebuf
++ // It may or may not be overwritten below
++ ::strncpy(ebuf, ::dlerror(), ebuflen-1);
++ ebuf[ebuflen-1]='\0';
++ int diag_msg_max_length=ebuflen-strlen(ebuf);
++ char* diag_msg_buf=ebuf+strlen(ebuf);
++
++ if (diag_msg_max_length==0) {
++ // No more space in ebuf for additional diagnostics message
++ return NULL;
++ }
++
++
++ int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
++
++ if (file_descriptor < 0) {
++ // Can't open library, report dlerror() message
++ return NULL;
++ }
++
++ bool failed_to_read_elf_head=
++ (sizeof(elf_head)!=
++ (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
++
++ ::close(file_descriptor);
++ if (failed_to_read_elf_head) {
++ // file i/o error - report dlerror() msg
++ return NULL;
++ }
++
++ typedef struct {
++ Elf32_Half code; // Actual value as defined in elf.h
++ Elf32_Half compat_class; // Compatibility of archs at VM's sense
++ char elf_class; // 32 or 64 bit
++ char endianess; // MSB or LSB
++ char* name; // String representation
++ } arch_t;
++
++ #ifndef EM_486
++ #define EM_486 6 /* Intel 80486 */
++ #endif
++
++ #ifndef EM_MIPS_RS3_LE
++ #define EM_MIPS_RS3_LE 10 /* MIPS */
++ #endif
++
++ #ifndef EM_PPC64
++ #define EM_PPC64 21 /* PowerPC64 */
++ #endif
++
++ #ifndef EM_S390
++ #define EM_S390 22 /* IBM System/390 */
++ #endif
++
++ #ifndef EM_IA_64
++ #define EM_IA_64 50 /* HP/Intel IA-64 */
++ #endif
++
++ #ifndef EM_X86_64
++ #define EM_X86_64 62 /* AMD x86-64 */
++ #endif
++
++ static const arch_t arch_array[]={
++ {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
++ {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
++ {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
++ {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
++ {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
++ {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
++ {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
++ {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
++ {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
++ {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
++ {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
++ {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
++ {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
++ {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
++ {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
++ {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
++ };
++
++ #if (defined IA32)
++ static Elf32_Half running_arch_code=EM_386;
++ #elif (defined AMD64)
++ static Elf32_Half running_arch_code=EM_X86_64;
++ #elif (defined IA64)
++ static Elf32_Half running_arch_code=EM_IA_64;
++ #elif (defined __sparc) && (defined _LP64)
++ static Elf32_Half running_arch_code=EM_SPARCV9;
++ #elif (defined __sparc) && (!defined _LP64)
++ static Elf32_Half running_arch_code=EM_SPARC;
++ #elif (defined __powerpc64__)
++ static Elf32_Half running_arch_code=EM_PPC64;
++ #elif (defined __powerpc__)
++ static Elf32_Half running_arch_code=EM_PPC;
++ #elif (defined ARM)
++ static Elf32_Half running_arch_code=EM_ARM;
++ #elif (defined S390)
++ static Elf32_Half running_arch_code=EM_S390;
++ #elif (defined ALPHA)
++ static Elf32_Half running_arch_code=EM_ALPHA;
++ #elif (defined MIPSEL)
++ static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
++ #elif (defined PARISC)
++ static Elf32_Half running_arch_code=EM_PARISC;
++ #elif (defined MIPS)
++ static Elf32_Half running_arch_code=EM_MIPS;
++ #elif (defined M68K)
++ static Elf32_Half running_arch_code=EM_68K;
++ #else
++ #error Method os::dll_load requires that one of following is defined:\
++ IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
++ #endif
++
++ // Identify compatability class for VM's architecture and library's architecture
++ // Obtain string descriptions for architectures
++
++ arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
++ int running_arch_index=-1;
++
++ for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
++ if (running_arch_code == arch_array[i].code) {
++ running_arch_index = i;
++ }
++ if (lib_arch.code == arch_array[i].code) {
++ lib_arch.compat_class = arch_array[i].compat_class;
++ lib_arch.name = arch_array[i].name;
++ }
++ }
++
++ assert(running_arch_index != -1,
++ "Didn't find running architecture code (running_arch_code) in arch_array");
++ if (running_arch_index == -1) {
++ // Even though running architecture detection failed
++ // we may still continue with reporting dlerror() message
++ return NULL;
++ }
++
++ if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
++ ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
++ return NULL;
++ }
++
++#ifndef S390
++ if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
++ ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
++ return NULL;
++ }
++#endif // !S390
++
++ if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
++ if ( lib_arch.name!=NULL ) {
++ ::snprintf(diag_msg_buf, diag_msg_max_length-1,
++ " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
++ lib_arch.name, arch_array[running_arch_index].name);
++ } else {
++ ::snprintf(diag_msg_buf, diag_msg_max_length-1,
++ " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
++ lib_arch.code,
++ arch_array[running_arch_index].name);
++ }
++ }
++
++ return NULL;
++}
++#endif /* !__APPLE__ */
++
++// XXX: Do we need a lock around this as per Linux?
++void* os::dll_lookup(void* handle, const char* name) {
++ return dlsym(handle, name);
++}
++
++
++static bool _print_ascii_file(const char* filename, outputStream* st) {
++ int fd = ::open(filename, O_RDONLY);
++ if (fd == -1) {
++ return false;
++ }
++
++ char buf[32];
++ int bytes;
++ while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
++ st->print_raw(buf, bytes);
++ }
++
++ ::close(fd);
++
++ return true;
++}
++
++void os::print_dll_info(outputStream *st) {
++ st->print_cr("Dynamic libraries:");
++#ifdef _ALLBSD_SOURCE
++#ifdef RTLD_DI_LINKMAP
++ Dl_info dli;
++ void *handle;
++ Link_map *map;
++ Link_map *p;
++
++ if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) {
++ st->print_cr("Error: Cannot print dynamic libraries.");
++ return;
++ }
++ handle = dlopen(dli.dli_fname, RTLD_LAZY);
++ if (handle == NULL) {
++ st->print_cr("Error: Cannot print dynamic libraries.");
++ return;
++ }
++ dlinfo(handle, RTLD_DI_LINKMAP, &map);
++ if (map == NULL) {
++ st->print_cr("Error: Cannot print dynamic libraries.");
++ return;
++ }
++
++ while (map->l_prev != NULL)
++ map = map->l_prev;
++
++ while (map != NULL) {
++ st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
++ map = map->l_next;
++ }
++
++ dlclose(handle);
++#elif defined(__APPLE__)
++ uint32_t count;
++ uint32_t i;
++
++ count = _dyld_image_count();
++ for (i = 1; i < count; i++) {
++ const char *name = _dyld_get_image_name(i);
++ intptr_t slide = _dyld_get_image_vmaddr_slide(i);
++ st->print_cr(PTR_FORMAT " \t%s", slide, name);
++ }
++#else
++ st->print_cr("Error: Cannot print dynamic libraries.");
++#endif
++#else
++ char fname[32];
++ pid_t pid = os::Bsd::gettid();
++
++ jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid);
++
++ if (!_print_ascii_file(fname, st)) {
++ st->print("Can not get library information for pid = %d\n", pid);
++ }
++#endif
++}
++
++
++void os::print_os_info(outputStream* st) {
++ st->print("OS:");
++
++ // Try to identify popular distros.
++ // Most Bsd distributions have /etc/XXX-release file, which contains
++ // the OS version string. Some have more than one /etc/XXX-release file
++ // (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
++ // so the order is important.
++ if (!_print_ascii_file("/etc/mandrake-release", st) &&
++ !_print_ascii_file("/etc/sun-release", st) &&
++ !_print_ascii_file("/etc/redhat-release", st) &&
++ !_print_ascii_file("/etc/SuSE-release", st) &&
++ !_print_ascii_file("/etc/turbobsd-release", st) &&
++ !_print_ascii_file("/etc/gentoo-release", st) &&
++ !_print_ascii_file("/etc/debian_version", st) &&
++ !_print_ascii_file("/etc/ltib-release", st) &&
++ !_print_ascii_file("/etc/angstrom-version", st)) {
++ st->print("Bsd");
++ }
++ st->cr();
++
++ // kernel
++ st->print("uname:");
++ struct utsname name;
++ uname(&name);
++ st->print(name.sysname); st->print(" ");
++ st->print(name.release); st->print(" ");
++ st->print(name.version); st->print(" ");
++ st->print(name.machine);
++ st->cr();
++
++#ifndef _ALLBSD_SOURCE
++ // Print warning if unsafe chroot environment detected
++ if (unsafe_chroot_detected) {
++ st->print("WARNING!! ");
++ st->print_cr(unstable_chroot_error);
++ }
++
++ // libc, pthread
++ st->print("libc:");
++ st->print(os::Bsd::glibc_version()); st->print(" ");
++ st->print(os::Bsd::libpthread_version()); st->print(" ");
++ if (os::Bsd::is_BsdThreads()) {
++ st->print("(%s stack)", os::Bsd::is_floating_stack() ? "floating" : "fixed");
++ }
++ st->cr();
++#endif
++
++ // rlimit
++ st->print("rlimit:");
++ struct rlimit rlim;
++
++ st->print(" STACK ");
++ getrlimit(RLIMIT_STACK, &rlim);
++ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
++ else st->print("%uk", rlim.rlim_cur >> 10);
++
++ st->print(", CORE ");
++ getrlimit(RLIMIT_CORE, &rlim);
++ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
++ else st->print("%uk", rlim.rlim_cur >> 10);
++
++ st->print(", NPROC ");
++ getrlimit(RLIMIT_NPROC, &rlim);
++ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
++ else st->print("%d", rlim.rlim_cur);
++
++ st->print(", NOFILE ");
++ getrlimit(RLIMIT_NOFILE, &rlim);
++ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
++ else st->print("%d", rlim.rlim_cur);
++
++#ifndef _ALLBSD_SOURCE
++ st->print(", AS ");
++ getrlimit(RLIMIT_AS, &rlim);
++ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
++ else st->print("%uk", rlim.rlim_cur >> 10);
++ st->cr();
++
++ // load average
++ st->print("load average:");
++ double loadavg[3];
++ os::loadavg(loadavg, 3);
++ st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
++ st->cr();
++#endif
++}
++
++void os::pd_print_cpu_info(outputStream* st) {
++ // Nothing to do for now.
++}
++
++void os::print_memory_info(outputStream* st) {
++
++ st->print("Memory:");
++ st->print(" %dk page", os::vm_page_size()>>10);
++
++#ifndef _ALLBSD_SOURCE
++ // values in struct sysinfo are "unsigned long"
++ struct sysinfo si;
++ sysinfo(&si);
++#endif
++
++ st->print(", physical " UINT64_FORMAT "k",
++ os::physical_memory() >> 10);
++ st->print("(" UINT64_FORMAT "k free)",
++ os::available_memory() >> 10);
++#ifndef _ALLBSD_SOURCE
++ st->print(", swap " UINT64_FORMAT "k",
++ ((jlong)si.totalswap * si.mem_unit) >> 10);
++ st->print("(" UINT64_FORMAT "k free)",
++ ((jlong)si.freeswap * si.mem_unit) >> 10);
++#endif
++ st->cr();
++
++ // meminfo
++ st->print("\n/proc/meminfo:\n");
++ _print_ascii_file("/proc/meminfo", st);
++ st->cr();
++}
++
++// Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific
++// but they're the same for all the bsd arch that we support
++// and they're the same for solaris but there's no common place to put this.
++const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
++ "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
++ "ILL_COPROC", "ILL_BADSTK" };
++
++const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
++ "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
++ "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" };
++
++const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
++
++const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
++
++void os::print_siginfo(outputStream* st, void* siginfo) {
++ st->print("siginfo:");
++
++ const int buflen = 100;
++ char buf[buflen];
++ siginfo_t *si = (siginfo_t*)siginfo;
++ st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
++ if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) {
++ st->print("si_errno=%s", buf);
++ } else {
++ st->print("si_errno=%d", si->si_errno);
++ }
++ const int c = si->si_code;
++ assert(c > 0, "unexpected si_code");
++ switch (si->si_signo) {
++ case SIGILL:
++ st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
++ st->print(", si_addr=" PTR_FORMAT, si->si_addr);
++ break;
++ case SIGFPE:
++ st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
++ st->print(", si_addr=" PTR_FORMAT, si->si_addr);
++ break;
++ case SIGSEGV:
++ st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
++ st->print(", si_addr=" PTR_FORMAT, si->si_addr);
++ break;
++ case SIGBUS:
++ st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
++ st->print(", si_addr=" PTR_FORMAT, si->si_addr);
++ break;
++ default:
++ st->print(", si_code=%d", si->si_code);
++ // no si_addr
++ }
++
++ if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
++ UseSharedSpaces) {
++ FileMapInfo* mapinfo = FileMapInfo::current_info();
++ if (mapinfo->is_in_shared_space(si->si_addr)) {
++ st->print("\n\nError accessing class data sharing archive." \
++ " Mapped file inaccessible during execution, " \
++ " possible disk/network problem.");
++ }
++ }
++ st->cr();
++}
++
++
++static void print_signal_handler(outputStream* st, int sig,
++ char* buf, size_t buflen);
++
++void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
++ st->print_cr("Signal Handlers:");
++ print_signal_handler(st, SIGSEGV, buf, buflen);
++ print_signal_handler(st, SIGBUS , buf, buflen);
++ print_signal_handler(st, SIGFPE , buf, buflen);
++ print_signal_handler(st, SIGPIPE, buf, buflen);
++ print_signal_handler(st, SIGXFSZ, buf, buflen);
++ print_signal_handler(st, SIGILL , buf, buflen);
++ print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
++ print_signal_handler(st, SR_signum, buf, buflen);
++ print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
++ print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
++ print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
++ print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
++}
++
++static char saved_jvm_path[MAXPATHLEN] = {0};
++
++// Find the full path to the current module, libjvm.so or libjvm_g.so
++void os::jvm_path(char *buf, jint buflen) {
++ // Error checking.
++ if (buflen < MAXPATHLEN) {
++ assert(false, "must use a large-enough buffer");
++ buf[0] = '\0';
++ return;
++ }
++ // Lazy resolve the path to current module.
++ if (saved_jvm_path[0] != 0) {
++ strcpy(buf, saved_jvm_path);
++ return;
++ }
++
++ char dli_fname[MAXPATHLEN];
++ bool ret = dll_address_to_library_name(
++ CAST_FROM_FN_PTR(address, os::jvm_path),
++ dli_fname, sizeof(dli_fname), NULL);
++ assert(ret != 0, "cannot locate libjvm");
++ char *rp = realpath(dli_fname, buf);
++ if (rp == NULL)
++ return;
++
++ if (Arguments::created_by_gamma_launcher()) {
++ // Support for the gamma launcher. Typical value for buf is
++ // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
++ // the right place in the string, then assume we are installed in a JDK and
++ // we're done. Otherwise, check for a JAVA_HOME environment variable and fix
++ // up the path so it looks like libjvm.so is installed there (append a
++ // fake suffix hotspot/libjvm.so).
++ const char *p = buf + strlen(buf) - 1;
++ for (int count = 0; p > buf && count < 5; ++count) {
++ for (--p; p > buf && *p != '/'; --p)
++ /* empty */ ;
++ }
++
++ if (strncmp(p, "/jre/lib/", 9) != 0) {
++ // Look for JAVA_HOME in the environment.
++ char* java_home_var = ::getenv("JAVA_HOME");
++ if (java_home_var != NULL && java_home_var[0] != 0) {
++ char* jrelib_p;
++ int len;
++
++ // Check the current module name "libjvm.so" or "libjvm_g.so".
++ p = strrchr(buf, '/');
++ assert(strstr(p, "/libjvm") == p, "invalid library name");
++ p = strstr(p, "_g") ? "_g" : "";
++
++ rp = realpath(java_home_var, buf);
++ if (rp == NULL)
++ return;
++
++ // determine if this is a legacy image or modules image
++ // modules image doesn't have "jre" subdirectory
++ len = strlen(buf);
++ jrelib_p = buf + len;
++ snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
++ if (0 != access(buf, F_OK)) {
++ snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
++ }
++
++ if (0 == access(buf, F_OK)) {
++ // Use current module name "libjvm[_g].so" instead of
++ // "libjvm"debug_only("_g")".so" since for fastdebug version
++ // we should have "libjvm.so" but debug_only("_g") adds "_g"!
++ len = strlen(buf);
++ snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p);
++ } else {
++ // Go back to path of .so
++ rp = realpath(dli_fname, buf);
++ if (rp == NULL)
++ return;
++ }
++ }
++ }
++ }
++
++ strcpy(saved_jvm_path, buf);
++}
++
++void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
++ // no prefix required, not even "_"
++}
++
++void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
++ // no suffix required
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// sun.misc.Signal support
++
++static volatile jint sigint_count = 0;
++
++static void
++UserHandler(int sig, void *siginfo, void *context) {
++ // 4511530 - sem_post is serialized and handled by the manager thread. When
++ // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
++ // don't want to flood the manager thread with sem_post requests.
++ if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
++ return;
++
++ // Ctrl-C is pressed during error reporting, likely because the error
++ // handler fails to abort. Let VM die immediately.
++ if (sig == SIGINT && is_error_reported()) {
++ os::die();
++ }
++
++ os::signal_notify(sig);
++}
++
++void* os::user_handler() {
++ return CAST_FROM_FN_PTR(void*, UserHandler);
++}
++
++extern "C" {
++ typedef void (*sa_handler_t)(int);
++ typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
++}
++
++void* os::signal(int signal_number, void* handler) {
++ struct sigaction sigAct, oldSigAct;
++
++ sigfillset(&(sigAct.sa_mask));
++ sigAct.sa_flags = SA_RESTART|SA_SIGINFO;
++ sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
++
++ if (sigaction(signal_number, &sigAct, &oldSigAct)) {
++ // -1 means registration failed
++ return (void *)-1;
++ }
++
++ return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
++}
++
++void os::signal_raise(int signal_number) {
++ ::raise(signal_number);
++}
++
++/*
++ * The following code is moved from os.cpp for making this
++ * code platform specific, which it is by its very nature.
++ */
++
++// Will be modified when max signal is changed to be dynamic
++int os::sigexitnum_pd() {
++ return NSIG;
++}
++
++// a counter for each possible signal value
++static volatile jint pending_signals[NSIG+1] = { 0 };
++
++// Bsd(POSIX) specific hand shaking semaphore.
++#ifdef __APPLE__
++static semaphore_t sig_sem;
++#define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value)
++#define SEM_WAIT(sem) semaphore_wait(sem);
++#define SEM_POST(sem) semaphore_signal(sem);
++#else
++static sem_t sig_sem;
++#define SEM_INIT(sem, value) sem_init(&sem, 0, value)
++#define SEM_WAIT(sem) sem_wait(&sem);
++#define SEM_POST(sem) sem_post(&sem);
++#endif
++
++void os::signal_init_pd() {
++ // Initialize signal structures
++ ::memset((void*)pending_signals, 0, sizeof(pending_signals));
++
++ // Initialize signal semaphore
++ ::SEM_INIT(sig_sem, 0);
++}
++
++void os::signal_notify(int sig) {
++ Atomic::inc(&pending_signals[sig]);
++ ::SEM_POST(sig_sem);
++}
++
++static int check_pending_signals(bool wait) {
++ Atomic::store(0, &sigint_count);
++ for (;;) {
++ for (int i = 0; i < NSIG + 1; i++) {
++ jint n = pending_signals[i];
++ if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
++ return i;
++ }
++ }
++ if (!wait) {
++ return -1;
++ }
++ JavaThread *thread = JavaThread::current();
++ ThreadBlockInVM tbivm(thread);
++
++ bool threadIsSuspended;
++ do {
++ thread->set_suspend_equivalent();
++ // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
++ ::SEM_WAIT(sig_sem);
++
++ // were we externally suspended while we were waiting?
++ threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
++ if (threadIsSuspended) {
++ //
++ // The semaphore has been incremented, but while we were waiting
++ // another thread suspended us. We don't want to continue running
++ // while suspended because that would surprise the thread that
++ // suspended us.
++ //
++ ::SEM_POST(sig_sem);
++
++ thread->java_suspend_self();
++ }
++ } while (threadIsSuspended);
++ }
++}
++
++int os::signal_lookup() {
++ return check_pending_signals(false);
++}
++
++int os::signal_wait() {
++ return check_pending_signals(true);
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// Virtual Memory
++
++int os::vm_page_size() {
++ // Seems redundant as all get out
++ assert(os::Bsd::page_size() != -1, "must call os::init");
++ return os::Bsd::page_size();
++}
++
++// Solaris allocates memory by pages.
++int os::vm_allocation_granularity() {
++ assert(os::Bsd::page_size() != -1, "must call os::init");
++ return os::Bsd::page_size();
++}
++
++// Rationale behind this function:
++// current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable
++// mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get
++// samples for JITted code. Here we create private executable mapping over the code cache
++// and then we can use standard (well, almost, as mapping can change) way to provide
++// info for the reporting script by storing timestamp and location of symbol
++void bsd_wrap_code(char* base, size_t size) {
++ static volatile jint cnt = 0;
++
++ if (!UseOprofile) {
++ return;
++ }
++
++ char buf[PATH_MAX + 1];
++ int num = Atomic::add(1, &cnt);
++
++ snprintf(buf, PATH_MAX + 1, "%s/hs-vm-%d-%d",
++ os::get_temp_directory(), os::current_process_id(), num);
++ unlink(buf);
++
++ int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU);
++
++ if (fd != -1) {
++ off_t rv = ::lseek(fd, size-2, SEEK_SET);
++ if (rv != (off_t)-1) {
++ if (::write(fd, "", 1) == 1) {
++ mmap(base, size,
++ PROT_READ|PROT_WRITE|PROT_EXEC,
++ MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0);
++ }
++ }
++ ::close(fd);
++ unlink(buf);
++ }
++}
++
++// NOTE: Bsd kernel does not really reserve the pages for us.
++// All it does is to check if there are enough free pages
++// left at the time of mmap(). This could be a potential
++// problem.
++bool os::commit_memory(char* addr, size_t size, bool exec) {
++ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
++#ifdef __OpenBSD__
++ // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
++ return ::mprotect(addr, size, prot) == 0;
++#else
++ uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
++ MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
++ return res != (uintptr_t) MAP_FAILED;
++#endif
++}
++
++#ifndef _ALLBSD_SOURCE
++// Define MAP_HUGETLB here so we can build HotSpot on old systems.
++#ifndef MAP_HUGETLB
++#define MAP_HUGETLB 0x40000
++#endif
++
++// Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
++#ifndef MADV_HUGEPAGE
++#define MADV_HUGEPAGE 14
++#endif
++#endif
++
++bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
++ bool exec) {
++#ifndef _ALLBSD_SOURCE
++ if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
++ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
++ uintptr_t res =
++ (uintptr_t) ::mmap(addr, size, prot,
++ MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
++ -1, 0);
++ return res != (uintptr_t) MAP_FAILED;
++ }
++#endif
++
++ return commit_memory(addr, size, exec);
++}
++
++void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
++#ifndef _ALLBSD_SOURCE
++ if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
++ // We don't check the return value: madvise(MADV_HUGEPAGE) may not
++ // be supported or the memory may already be backed by huge pages.
++ ::madvise(addr, bytes, MADV_HUGEPAGE);
++ }
++#endif
++}
++
++void os::free_memory(char *addr, size_t bytes) {
++ ::madvise(addr, bytes, MADV_DONTNEED);
++}
++
++void os::numa_make_global(char *addr, size_t bytes) {
++}
++
++void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
++}
++
++bool os::numa_topology_changed() { return false; }
++
++size_t os::numa_get_groups_num() {
++ return 1;
++}
++
++int os::numa_get_group_id() {
++ return 0;
++}
++
++size_t os::numa_get_leaf_groups(int *ids, size_t size) {
++ if (size > 0) {
++ ids[0] = 0;
++ return 1;
++ }
++ return 0;
++}
++
++bool os::get_page_info(char *start, page_info* info) {
++ return false;
++}
++
++char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
++ return end;
++}
++
++#ifndef _ALLBSD_SOURCE
++// Something to do with the numa-aware allocator needs these symbols
++extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
++extern "C" JNIEXPORT void numa_error(char *where) { }
++extern "C" JNIEXPORT int fork1() { return fork(); }
++
++
++// If we are running with libnuma version > 2, then we should
++// be trying to use symbols with versions 1.1
++// If we are running with earlier version, which did not have symbol versions,
++// we should use the base version.
++void* os::Bsd::libnuma_dlsym(void* handle, const char *name) {
++ void *f = dlvsym(handle, name, "libnuma_1.1");
++ if (f == NULL) {
++ f = dlsym(handle, name);
++ }
++ return f;
++}
++
++bool os::Bsd::libnuma_init() {
++ // sched_getcpu() should be in libc.
++ set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
++ dlsym(RTLD_DEFAULT, "sched_getcpu")));
++
++ if (sched_getcpu() != -1) { // Does it work?
++ void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
++ if (handle != NULL) {
++ set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t,
++ libnuma_dlsym(handle, "numa_node_to_cpus")));
++ set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t,
++ libnuma_dlsym(handle, "numa_max_node")));
++ set_numa_available(CAST_TO_FN_PTR(numa_available_func_t,
++ libnuma_dlsym(handle, "numa_available")));
++ set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
++ libnuma_dlsym(handle, "numa_tonode_memory")));
++ set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
++ libnuma_dlsym(handle, "numa_interleave_memory")));
++
++
++ if (numa_available() != -1) {
++ set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
++ // Create a cpu -> node mapping
++ _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
++ rebuild_cpu_to_node_map();
++ return true;
++ }
++ }
++ }
++ return false;
++}
++
++// rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
++// The table is later used in get_node_by_cpu().
++void os::Bsd::rebuild_cpu_to_node_map() {
++ const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
++ // in libnuma (possible values are starting from 16,
++ // and continuing up with every other power of 2, but less
++ // than the maximum number of CPUs supported by kernel), and
++ // is a subject to change (in libnuma version 2 the requirements
++ // are more reasonable) we'll just hardcode the number they use
++ // in the library.
++ const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
++
++ size_t cpu_num = os::active_processor_count();
++ size_t cpu_map_size = NCPUS / BitsPerCLong;
++ size_t cpu_map_valid_size =
++ MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
++
++ cpu_to_node()->clear();
++ cpu_to_node()->at_grow(cpu_num - 1);
++ size_t node_num = numa_get_groups_num();
++
++ unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size);
++ for (size_t i = 0; i < node_num; i++) {
++ if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
++ for (size_t j = 0; j < cpu_map_valid_size; j++) {
++ if (cpu_map[j] != 0) {
++ for (size_t k = 0; k < BitsPerCLong; k++) {
++ if (cpu_map[j] & (1UL << k)) {
++ cpu_to_node()->at_put(j * BitsPerCLong + k, i);
++ }
++ }
++ }
++ }
++ }
++ }
++ FREE_C_HEAP_ARRAY(unsigned long, cpu_map);
++}
++
++int os::Bsd::get_node_by_cpu(int cpu_id) {
++ if (cpu_to_node() != NULL && cpu_id >= 0 && cpu_id < cpu_to_node()->length()) {
++ return cpu_to_node()->at(cpu_id);
++ }
++ return -1;
++}
++
++GrowableArray<int>* os::Bsd::_cpu_to_node;
++os::Bsd::sched_getcpu_func_t os::Bsd::_sched_getcpu;
++os::Bsd::numa_node_to_cpus_func_t os::Bsd::_numa_node_to_cpus;
++os::Bsd::numa_max_node_func_t os::Bsd::_numa_max_node;
++os::Bsd::numa_available_func_t os::Bsd::_numa_available;
++os::Bsd::numa_tonode_memory_func_t os::Bsd::_numa_tonode_memory;
++os::Bsd::numa_interleave_memory_func_t os::Bsd::_numa_interleave_memory;
++unsigned long* os::Bsd::_numa_all_nodes;
++#endif
++
++bool os::uncommit_memory(char* addr, size_t size) {
++#ifdef __OpenBSD__
++ // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
++ return ::mprotect(addr, size, PROT_NONE) == 0;
++#else
++ uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
++ MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
++ return res != (uintptr_t) MAP_FAILED;
++#endif
++}
++
++bool os::create_stack_guard_pages(char* addr, size_t size) {
++ return os::commit_memory(addr, size);
++}
++
++// If this is a growable mapping, remove the guard pages entirely by
++// munmap()ping them. If not, just call uncommit_memory().
++bool os::remove_stack_guard_pages(char* addr, size_t size) {
++ return os::uncommit_memory(addr, size);
++}
++
++static address _highest_vm_reserved_address = NULL;
++
++// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
++// at 'requested_addr'. If there are existing memory mappings at the same
++// location, however, they will be overwritten. If 'fixed' is false,
++// 'requested_addr' is only treated as a hint, the return value may or
++// may not start from the requested address. Unlike Bsd mmap(), this
++// function returns NULL to indicate failure.
++static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
++ char * addr;
++ int flags;
++
++ flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
++ if (fixed) {
++ assert((uintptr_t)requested_addr % os::Bsd::page_size() == 0, "unaligned address");
++ flags |= MAP_FIXED;
++ }
++
++ // Map uncommitted pages PROT_READ and PROT_WRITE, change access
++ // to PROT_EXEC if executable when we commit the page.
++ addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE,
++ flags, -1, 0);
++
++ if (addr != MAP_FAILED) {
++ // anon_mmap() should only get called during VM initialization,
++ // don't need lock (actually we can skip locking even it can be called
++ // from multiple threads, because _highest_vm_reserved_address is just a
++ // hint about the upper limit of non-stack memory regions.)
++ if ((address)addr + bytes > _highest_vm_reserved_address) {
++ _highest_vm_reserved_address = (address)addr + bytes;
++ }
++ }
++
++ return addr == MAP_FAILED ? NULL : addr;
++}
++
++// Don't update _highest_vm_reserved_address, because there might be memory
++// regions above addr + size. If so, releasing a memory region only creates
++// a hole in the address space, it doesn't help prevent heap-stack collision.
++//
++static int anon_munmap(char * addr, size_t size) {
++ return ::munmap(addr, size) == 0;
++}
++
++char* os::reserve_memory(size_t bytes, char* requested_addr,
++ size_t alignment_hint) {
++ return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
++}
++
++bool os::release_memory(char* addr, size_t size) {
++ return anon_munmap(addr, size);
++}
++
++static address highest_vm_reserved_address() {
++ return _highest_vm_reserved_address;
++}
++
++static bool bsd_mprotect(char* addr, size_t size, int prot) {
++ // Bsd wants the mprotect address argument to be page aligned.
++ char* bottom = (char*)align_size_down((intptr_t)addr, os::Bsd::page_size());
++
++ // According to SUSv3, mprotect() should only be used with mappings
++ // established by mmap(), and mmap() always maps whole pages. Unaligned
++ // 'addr' likely indicates problem in the VM (e.g. trying to change
++ // protection of malloc'ed or statically allocated memory). Check the
++ // caller if you hit this assert.
++ assert(addr == bottom, "sanity check");
++
++ size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Bsd::page_size());
++ return ::mprotect(bottom, size, prot) == 0;
++}
++
++// Set protections specified
++bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
++ bool is_committed) {
++ unsigned int p = 0;
++ switch (prot) {
++ case MEM_PROT_NONE: p = PROT_NONE; break;
++ case MEM_PROT_READ: p = PROT_READ; break;
++ case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
++ case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
++ default:
++ ShouldNotReachHere();
++ }
++ // is_committed is unused.
++ return bsd_mprotect(addr, bytes, p);
++}
++
++bool os::guard_memory(char* addr, size_t size) {
++ return bsd_mprotect(addr, size, PROT_NONE);
++}
++
++bool os::unguard_memory(char* addr, size_t size) {
++ return bsd_mprotect(addr, size, PROT_READ|PROT_WRITE);
++}
++
++bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) {
++ bool result = false;
++#ifndef _ALLBSD_SOURCE
++ void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
++ MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
++ -1, 0);
++
++ if (p != (void *) -1) {
++ // We don't know if this really is a huge page or not.
++ FILE *fp = fopen("/proc/self/maps", "r");
++ if (fp) {
++ while (!feof(fp)) {
++ char chars[257];
++ long x = 0;
++ if (fgets(chars, sizeof(chars), fp)) {
++ if (sscanf(chars, "%lx-%*x", &x) == 1
++ && x == (long)p) {
++ if (strstr (chars, "hugepage")) {
++ result = true;
++ break;
++ }
++ }
++ }
++ }
++ fclose(fp);
++ }
++ munmap (p, page_size);
++ if (result)
++ return true;
++ }
++
++ if (warn) {
++ warning("HugeTLBFS is not supported by the operating system.");
++ }
++#endif
++
++ return result;
++}
++
++/*
++* Set the coredump_filter bits to include largepages in core dump (bit 6)
++*
++* From the coredump_filter documentation:
++*
++* - (bit 0) anonymous private memory
++* - (bit 1) anonymous shared memory
++* - (bit 2) file-backed private memory
++* - (bit 3) file-backed shared memory
++* - (bit 4) ELF header pages in file-backed private memory areas (it is
++* effective only if the bit 2 is cleared)
++* - (bit 5) hugetlb private memory
++* - (bit 6) hugetlb shared memory
++*/
++static void set_coredump_filter(void) {
++ FILE *f;
++ long cdm;
++
++ if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
++ return;
++ }
++
++ if (fscanf(f, "%lx", &cdm) != 1) {
++ fclose(f);
++ return;
++ }
++
++ rewind(f);
++
++ if ((cdm & LARGEPAGES_BIT) == 0) {
++ cdm |= LARGEPAGES_BIT;
++ fprintf(f, "%#lx", cdm);
++ }
++
++ fclose(f);
++}
++
++// Large page support
++
++static size_t _large_page_size = 0;
++
++void os::large_page_init() {
++#ifndef _ALLBSD_SOURCE
++ if (!UseLargePages) {
++ UseHugeTLBFS = false;
++ UseSHM = false;
++ return;
++ }
++
++ if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
++ // If UseLargePages is specified on the command line try both methods,
++ // if it's default, then try only HugeTLBFS.
++ if (FLAG_IS_DEFAULT(UseLargePages)) {
++ UseHugeTLBFS = true;
++ } else {
++ UseHugeTLBFS = UseSHM = true;
++ }
++ }
++
++ if (LargePageSizeInBytes) {
++ _large_page_size = LargePageSizeInBytes;
++ } else {
++ // large_page_size on Bsd is used to round up heap size. x86 uses either
++ // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
++ // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
++ // page as large as 256M.
++ //
++ // Here we try to figure out page size by parsing /proc/meminfo and looking
++ // for a line with the following format:
++ // Hugepagesize: 2048 kB
++ //
++ // If we can't determine the value (e.g. /proc is not mounted, or the text
++ // format has been changed), we'll use the largest page size supported by
++ // the processor.
++
++#ifndef ZERO
++ _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
++ ARM_ONLY(2 * M) PPC_ONLY(4 * M);
++#endif // ZERO
++
++ FILE *fp = fopen("/proc/meminfo", "r");
++ if (fp) {
++ while (!feof(fp)) {
++ int x = 0;
++ char buf[16];
++ if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
++ if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
++ _large_page_size = x * K;
++ break;
++ }
++ } else {
++ // skip to next line
++ for (;;) {
++ int ch = fgetc(fp);
++ if (ch == EOF || ch == (int)'\n') break;
++ }
++ }
++ }
++ fclose(fp);
++ }
++ }
++
++ // print a warning if any large page related flag is specified on command line
++ bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
++
++ const size_t default_page_size = (size_t)Bsd::page_size();
++ if (_large_page_size > default_page_size) {
++ _page_sizes[0] = _large_page_size;
++ _page_sizes[1] = default_page_size;
++ _page_sizes[2] = 0;
++ }
++ UseHugeTLBFS = UseHugeTLBFS &&
++ Bsd::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
++
++ if (UseHugeTLBFS)
++ UseSHM = false;
++
++ UseLargePages = UseHugeTLBFS || UseSHM;
++
++ set_coredump_filter();
++#endif
++}
++
++#ifndef _ALLBSD_SOURCE
++#ifndef SHM_HUGETLB
++#define SHM_HUGETLB 04000
++#endif
++#endif
++
++char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
++ // "exec" is passed in but not used. Creating the shared image for
++ // the code cache doesn't have an SHM_X executable permission to check.
++ assert(UseLargePages && UseSHM, "only for SHM large pages");
++
++ key_t key = IPC_PRIVATE;
++ char *addr;
++
++ bool warn_on_failure = UseLargePages &&
++ (!FLAG_IS_DEFAULT(UseLargePages) ||
++ !FLAG_IS_DEFAULT(LargePageSizeInBytes)
++ );
++ char msg[128];
++
++ // Create a large shared memory region to attach to based on size.
++ // Currently, size is the total size of the heap
++#ifndef _ALLBSD_SOURCE
++ int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
++#else
++ int shmid = shmget(key, bytes, IPC_CREAT|SHM_R|SHM_W);
++#endif
++ if (shmid == -1) {
++ // Possible reasons for shmget failure:
++ // 1. shmmax is too small for Java heap.
++ // > check shmmax value: cat /proc/sys/kernel/shmmax
++ // > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax
++ // 2. not enough large page memory.
++ // > check available large pages: cat /proc/meminfo
++ // > increase amount of large pages:
++ // echo new_value > /proc/sys/vm/nr_hugepages
++ // Note 1: different Bsd may use different name for this property,
++ // e.g. on Redhat AS-3 it is "hugetlb_pool".
++ // Note 2: it's possible there's enough physical memory available but
++ // they are so fragmented after a long run that they can't
++ // coalesce into large pages. Try to reserve large pages when
++ // the system is still "fresh".
++ if (warn_on_failure) {
++ jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
++ warning(msg);
++ }
++ return NULL;
++ }
++
++ // attach to the region
++ addr = (char*)shmat(shmid, req_addr, 0);
++ int err = errno;
++
++ // Remove shmid. If shmat() is successful, the actual shared memory segment
++ // will be deleted when it's detached by shmdt() or when the process
++ // terminates. If shmat() is not successful this will remove the shared
++ // segment immediately.
++ shmctl(shmid, IPC_RMID, NULL);
++
++ if ((intptr_t)addr == -1) {
++ if (warn_on_failure) {
++ jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
++ warning(msg);
++ }
++ return NULL;
++ }
++
++ return addr;
++}
++
++bool os::release_memory_special(char* base, size_t bytes) {
++ // detaching the SHM segment will also delete it, see reserve_memory_special()
++ int rslt = shmdt(base);
++ return rslt == 0;
++}
++
++size_t os::large_page_size() {
++ return _large_page_size;
++}
++
++// HugeTLBFS allows application to commit large page memory on demand;
++// with SysV SHM the entire memory region must be allocated as shared
++// memory.
++bool os::can_commit_large_page_memory() {
++ return UseHugeTLBFS;
++}
++
++bool os::can_execute_large_page_memory() {
++ return UseHugeTLBFS;
++}
++
++// Reserve memory at an arbitrary address, only if that area is
++// available (and not reserved for something else).
++
++char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
++ const int max_tries = 10;
++ char* base[max_tries];
++ size_t size[max_tries];
++ const size_t gap = 0x000000;
++
++ // Assert only that the size is a multiple of the page size, since
++ // that's all that mmap requires, and since that's all we really know
++ // about at this low abstraction level. If we need higher alignment,
++ // we can either pass an alignment to this method or verify alignment
++ // in one of the methods further up the call chain. See bug 5044738.
++ assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
++
++ // Repeatedly allocate blocks until the block is allocated at the
++ // right spot. Give up after max_tries. Note that reserve_memory() will
++ // automatically update _highest_vm_reserved_address if the call is
++ // successful. The variable tracks the highest memory address every reserved
++ // by JVM. It is used to detect heap-stack collision if running with
++ // fixed-stack BsdThreads. Because here we may attempt to reserve more
++ // space than needed, it could confuse the collision detecting code. To
++ // solve the problem, save current _highest_vm_reserved_address and
++ // calculate the correct value before return.
++ address old_highest = _highest_vm_reserved_address;
++
++ // Bsd mmap allows caller to pass an address as hint; give it a try first,
++ // if kernel honors the hint then we can return immediately.
++ char * addr = anon_mmap(requested_addr, bytes, false);
++ if (addr == requested_addr) {
++ return requested_addr;
++ }
++
++ if (addr != NULL) {
++ // mmap() is successful but it fails to reserve at the requested address
++ anon_munmap(addr, bytes);
++ }
++
++ int i;
++ for (i = 0; i < max_tries; ++i) {
++ base[i] = reserve_memory(bytes);
++
++ if (base[i] != NULL) {
++ // Is this the block we wanted?
++ if (base[i] == requested_addr) {
++ size[i] = bytes;
++ break;
++ }
++
++ // Does this overlap the block we wanted? Give back the overlapped
++ // parts and try again.
++
++ size_t top_overlap = requested_addr + (bytes + gap) - base[i];
++ if (top_overlap >= 0 && top_overlap < bytes) {
++ unmap_memory(base[i], top_overlap);
++ base[i] += top_overlap;
++ size[i] = bytes - top_overlap;
++ } else {
++ size_t bottom_overlap = base[i] + bytes - requested_addr;
++ if (bottom_overlap >= 0 && bottom_overlap < bytes) {
++ unmap_memory(requested_addr, bottom_overlap);
++ size[i] = bytes - bottom_overlap;
++ } else {
++ size[i] = bytes;
++ }
++ }
++ }
++ }
++
++ // Give back the unused reserved pieces.
++
++ for (int j = 0; j < i; ++j) {
++ if (base[j] != NULL) {
++ unmap_memory(base[j], size[j]);
++ }
++ }
++
++ if (i < max_tries) {
++ _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
++ return requested_addr;
++ } else {
++ _highest_vm_reserved_address = old_highest;
++ return NULL;
++ }
++}
++
++size_t os::read(int fd, void *buf, unsigned int nBytes) {
++ RESTARTABLE_RETURN_INT(::read(fd, buf, nBytes));
++}
++
++// TODO-FIXME: reconcile Solaris' os::sleep with the bsd variation.
++// Solaris uses poll(), bsd uses park().
++// Poll() is likely a better choice, assuming that Thread.interrupt()
++// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
++// SIGSEGV, see 4355769.
++
++const int NANOSECS_PER_MILLISECS = 1000000;
++
++int os::sleep(Thread* thread, jlong millis, bool interruptible) {
++ assert(thread == Thread::current(), "thread consistency check");
++
++ ParkEvent * const slp = thread->_SleepEvent ;
++ slp->reset() ;
++ OrderAccess::fence() ;
++
++ if (interruptible) {
++ jlong prevtime = javaTimeNanos();
++
++ for (;;) {
++ if (os::is_interrupted(thread, true)) {
++ return OS_INTRPT;
++ }
++
++ jlong newtime = javaTimeNanos();
++
++ if (newtime - prevtime < 0) {
++ // time moving backwards, should only happen if no monotonic clock
++ // not a guarantee() because JVM should not abort on kernel/glibc bugs
++ assert(!Bsd::supports_monotonic_clock(), "time moving backwards");
++ } else {
++ millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
++ }
++
++ if(millis <= 0) {
++ return OS_OK;
++ }
++
++ prevtime = newtime;
++
++ {
++ assert(thread->is_Java_thread(), "sanity check");
++ JavaThread *jt = (JavaThread *) thread;
++ ThreadBlockInVM tbivm(jt);
++ OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
++
++ jt->set_suspend_equivalent();
++ // cleared by handle_special_suspend_equivalent_condition() or
++ // java_suspend_self() via check_and_wait_while_suspended()
++
++ slp->park(millis);
++
++ // were we externally suspended while we were waiting?
++ jt->check_and_wait_while_suspended();
++ }
++ }
++ } else {
++ OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
++ jlong prevtime = javaTimeNanos();
++
++ for (;;) {
++ // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
++ // the 1st iteration ...
++ jlong newtime = javaTimeNanos();
++
++ if (newtime - prevtime < 0) {
++ // time moving backwards, should only happen if no monotonic clock
++ // not a guarantee() because JVM should not abort on kernel/glibc bugs
++ assert(!Bsd::supports_monotonic_clock(), "time moving backwards");
++ } else {
++ millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
++ }
++
++ if(millis <= 0) break ;
++
++ prevtime = newtime;
++ slp->park(millis);
++ }
++ return OS_OK ;
++ }
++}
++
++int os::naked_sleep() {
++ // %% make the sleep time an integer flag. for now use 1 millisec.
++ return os::sleep(Thread::current(), 1, false);
++}
++
++// Sleep forever; naked call to OS-specific sleep; use with CAUTION
++void os::infinite_sleep() {
++ while (true) { // sleep forever ...
++ ::sleep(100); // ... 100 seconds at a time
++ }
++}
++
++// Used to convert frequent JVM_Yield() to nops
++bool os::dont_yield() {
++ return DontYieldALot;
++}
++
++void os::yield() {
++ sched_yield();
++}
++
++os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
++
++void os::yield_all(int attempts) {
++ // Yields to all threads, including threads with lower priorities
++ // Threads on Bsd are all with same priority. The Solaris style
++ // os::yield_all() with nanosleep(1ms) is not necessary.
++ sched_yield();
++}
++
++// Called from the tight loops to possibly influence time-sharing heuristics
++void os::loop_breaker(int attempts) {
++ os::yield_all(attempts);
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// thread priority support
++
++// Note: Normal Bsd applications are run with SCHED_OTHER policy. SCHED_OTHER
++// only supports dynamic priority, static priority must be zero. For real-time
++// applications, Bsd supports SCHED_RR which allows static priority (1-99).
++// However, for large multi-threaded applications, SCHED_RR is not only slower
++// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
++// of 5 runs - Sep 2005).
++//
++// The following code actually changes the niceness of kernel-thread/LWP. It
++// has an assumption that setpriority() only modifies one kernel-thread/LWP,
++// not the entire user process, and user level threads are 1:1 mapped to kernel
++// threads. It has always been the case, but could change in the future. For
++// this reason, the code should not be used as default (ThreadPriorityPolicy=0).
++// It is only used when ThreadPriorityPolicy=1 and requires root privilege.
++
++#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__)
++int os::java_to_os_priority[MaxPriority + 1] = {
++ 19, // 0 Entry should never be used
++
++ 0, // 1 MinPriority
++ 3, // 2
++ 6, // 3
++
++ 10, // 4
++ 15, // 5 NormPriority
++ 18, // 6
++
++ 21, // 7
++ 25, // 8
++ 28, // 9 NearMaxPriority
++
++ 31 // 10 MaxPriority
++};
++#elif defined(__APPLE__)
++/* Using Mach high-level priority assignments */
++int os::java_to_os_priority[MaxPriority + 1] = {
++ 0, // 0 Entry should never be used (MINPRI_USER)
++
++ 27, // 1 MinPriority
++ 28, // 2
++ 29, // 3
++
++ 30, // 4
++ 31, // 5 NormPriority (BASEPRI_DEFAULT)
++ 32, // 6
++
++ 33, // 7
++ 34, // 8
++ 35, // 9 NearMaxPriority
++
++ 36 // 10 MaxPriority
++};
++#else
++int os::java_to_os_priority[MaxPriority + 1] = {
++ 19, // 0 Entry should never be used
++
++ 4, // 1 MinPriority
++ 3, // 2
++ 2, // 3
++
++ 1, // 4
++ 0, // 5 NormPriority
++ -1, // 6
++
++ -2, // 7
++ -3, // 8
++ -4, // 9 NearMaxPriority
++
++ -5 // 10 MaxPriority
++};
++#endif
++
++static int prio_init() {
++ if (ThreadPriorityPolicy == 1) {
++ // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
++ // if effective uid is not root. Perhaps, a more elegant way of doing
++ // this is to test CAP_SYS_NICE capability, but that will require libcap.so
++ if (geteuid() != 0) {
++ if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
++ warning("-XX:ThreadPriorityPolicy requires root privilege on Bsd");
++ }
++ ThreadPriorityPolicy = 0;
++ }
++ }
++ return 0;
++}
++
++OSReturn os::set_native_priority(Thread* thread, int newpri) {
++ if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
++
++#ifdef __OpenBSD__
++ // OpenBSD pthread_setprio starves low priority threads
++ return OS_OK;
++#elif defined(__FreeBSD__)
++ int ret = pthread_setprio(thread->osthread()->pthread_id(), newpri);
++#elif defined(__APPLE__) || defined(__NetBSD__)
++ struct sched_param sp;
++ int policy;
++ pthread_t self = pthread_self();
++
++ if (pthread_getschedparam(self, &policy, &sp) != 0)
++ return OS_ERR;
++
++ sp.sched_priority = newpri;
++ if (pthread_setschedparam(self, policy, &sp) != 0)
++ return OS_ERR;
++
++ return OS_OK;
++#else
++ int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
++ return (ret == 0) ? OS_OK : OS_ERR;
++#endif
++}
++
++OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
++ if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
++ *priority_ptr = java_to_os_priority[NormPriority];
++ return OS_OK;
++ }
++
++ errno = 0;
++#if defined(__OpenBSD__) || defined(__FreeBSD__)
++ *priority_ptr = pthread_getprio(thread->osthread()->pthread_id());
++#elif defined(__APPLE__) || defined(__NetBSD__)
++ int policy;
++ struct sched_param sp;
++
++ pthread_getschedparam(pthread_self(), &policy, &sp);
++ *priority_ptr = sp.sched_priority;
++#else
++ *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());
++#endif
++ return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
++}
++
++// Hint to the underlying OS that a task switch would not be good.
++// Void return because it's a hint and can fail.
++void os::hint_no_preempt() {}
++
++////////////////////////////////////////////////////////////////////////////////
++// suspend/resume support
++
++// the low-level signal-based suspend/resume support is a remnant from the
++// old VM-suspension that used to be for java-suspension, safepoints etc,
++// within hotspot. Now there is a single use-case for this:
++// - calling get_thread_pc() on the VMThread by the flat-profiler task
++// that runs in the watcher thread.
++// The remaining code is greatly simplified from the more general suspension
++// code that used to be used.
++//
++// The protocol is quite simple:
++// - suspend:
++// - sends a signal to the target thread
++// - polls the suspend state of the osthread using a yield loop
++// - target thread signal handler (SR_handler) sets suspend state
++// and blocks in sigsuspend until continued
++// - resume:
++// - sets target osthread state to continue
++// - sends signal to end the sigsuspend loop in the SR_handler
++//
++// Note that the SR_lock plays no role in this suspend/resume protocol.
++//
++
++static void resume_clear_context(OSThread *osthread) {
++ osthread->set_ucontext(NULL);
++ osthread->set_siginfo(NULL);
++
++ // notify the suspend action is completed, we have now resumed
++ osthread->sr.clear_suspended();
++}
++
++static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
++ osthread->set_ucontext(context);
++ osthread->set_siginfo(siginfo);
++}
++
++//
++// Handler function invoked when a thread's execution is suspended or
++// resumed. We have to be careful that only async-safe functions are
++// called here (Note: most pthread functions are not async safe and
++// should be avoided.)
++//
++// Note: sigwait() is a more natural fit than sigsuspend() from an
++// interface point of view, but sigwait() prevents the signal hander
++// from being run. libpthread would get very confused by not having
++// its signal handlers run and prevents sigwait()'s use with the
++// mutex granting granting signal.
++//
++// Currently only ever called on the VMThread
++//
++static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
++ // Save and restore errno to avoid confusing native code with EINTR
++ // after sigsuspend.
++ int old_errno = errno;
++
++ Thread* thread = Thread::current();
++ OSThread* osthread = thread->osthread();
++ assert(thread->is_VM_thread(), "Must be VMThread");
++ // read current suspend action
++ int action = osthread->sr.suspend_action();
++ if (action == SR_SUSPEND) {
++ suspend_save_context(osthread, siginfo, context);
++
++ // Notify the suspend action is about to be completed. do_suspend()
++ // waits until SR_SUSPENDED is set and then returns. We will wait
++ // here for a resume signal and that completes the suspend-other
++ // action. do_suspend/do_resume is always called as a pair from
++ // the same thread - so there are no races
++
++ // notify the caller
++ osthread->sr.set_suspended();
++
++ sigset_t suspend_set; // signals for sigsuspend()
++
++ // get current set of blocked signals and unblock resume signal
++ pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
++ sigdelset(&suspend_set, SR_signum);
++
++ // wait here until we are resumed
++ do {
++ sigsuspend(&suspend_set);
++ // ignore all returns until we get a resume signal
++ } while (osthread->sr.suspend_action() != SR_CONTINUE);
++
++ resume_clear_context(osthread);
++
++ } else {
++ assert(action == SR_CONTINUE, "unexpected sr action");
++ // nothing special to do - just leave the handler
++ }
++
++ errno = old_errno;
++}
++
++
++static int SR_initialize() {
++ struct sigaction act;
++ char *s;
++ /* Get signal number to use for suspend/resume */
++ if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
++ int sig = ::strtol(s, 0, 10);
++ if (sig > 0 || sig < NSIG) {
++ SR_signum = sig;
++ }
++ }
++
++ assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
++ "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
++
++ sigemptyset(&SR_sigset);
++ sigaddset(&SR_sigset, SR_signum);
++
++ /* Set up signal handler for suspend/resume */
++ act.sa_flags = SA_RESTART|SA_SIGINFO;
++ act.sa_handler = (void (*)(int)) SR_handler;
++
++ // SR_signum is blocked by default.
++ // 4528190 - We also need to block pthread restart signal (32 on all
++ // supported Bsd platforms). Note that BsdThreads need to block
++ // this signal for all threads to work properly. So we don't have
++ // to use hard-coded signal number when setting up the mask.
++ pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
++
++ if (sigaction(SR_signum, &act, 0) == -1) {
++ return -1;
++ }
++
++ // Save signal flag
++ os::Bsd::set_our_sigflags(SR_signum, act.sa_flags);
++ return 0;
++}
++
++static int SR_finalize() {
++ return 0;
++}
++
++
++// returns true on success and false on error - really an error is fatal
++// but this seems the normal response to library errors
++static bool do_suspend(OSThread* osthread) {
++ // mark as suspended and send signal
++ osthread->sr.set_suspend_action(SR_SUSPEND);
++ int status = pthread_kill(osthread->pthread_id(), SR_signum);
++ assert_status(status == 0, status, "pthread_kill");
++
++ // check status and wait until notified of suspension
++ if (status == 0) {
++ for (int i = 0; !osthread->sr.is_suspended(); i++) {
++ os::yield_all(i);
++ }
++ osthread->sr.set_suspend_action(SR_NONE);
++ return true;
++ }
++ else {
++ osthread->sr.set_suspend_action(SR_NONE);
++ return false;
++ }
++}
++
++static void do_resume(OSThread* osthread) {
++ assert(osthread->sr.is_suspended(), "thread should be suspended");
++ osthread->sr.set_suspend_action(SR_CONTINUE);
++
++ int status = pthread_kill(osthread->pthread_id(), SR_signum);
++ assert_status(status == 0, status, "pthread_kill");
++ // check status and wait unit notified of resumption
++ if (status == 0) {
++ for (int i = 0; osthread->sr.is_suspended(); i++) {
++ os::yield_all(i);
++ }
++ }
++ osthread->sr.set_suspend_action(SR_NONE);
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// interrupt support
++
++void os::interrupt(Thread* thread) {
++ assert(Thread::current() == thread || Threads_lock->owned_by_self(),
++ "possibility of dangling Thread pointer");
++
++ OSThread* osthread = thread->osthread();
++
++ if (!osthread->interrupted()) {
++ osthread->set_interrupted(true);
++ // More than one thread can get here with the same value of osthread,
++ // resulting in multiple notifications. We do, however, want the store
++ // to interrupted() to be visible to other threads before we execute unpark().
++ OrderAccess::fence();
++ ParkEvent * const slp = thread->_SleepEvent ;
++ if (slp != NULL) slp->unpark() ;
++ }
++
++ // For JSR166. Unpark even if interrupt status already was set
++ if (thread->is_Java_thread())
++ ((JavaThread*)thread)->parker()->unpark();
++
++ ParkEvent * ev = thread->_ParkEvent ;
++ if (ev != NULL) ev->unpark() ;
++
++}
++
++bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
++ assert(Thread::current() == thread || Threads_lock->owned_by_self(),
++ "possibility of dangling Thread pointer");
++
++ OSThread* osthread = thread->osthread();
++
++ bool interrupted = osthread->interrupted();
++
++ if (interrupted && clear_interrupted) {
++ osthread->set_interrupted(false);
++ // consider thread->_SleepEvent->reset() ... optional optimization
++ }
++
++ return interrupted;
++}
++
++///////////////////////////////////////////////////////////////////////////////////
++// signal handling (except suspend/resume)
++
++// This routine may be used by user applications as a "hook" to catch signals.
++// The user-defined signal handler must pass unrecognized signals to this
++// routine, and if it returns true (non-zero), then the signal handler must
++// return immediately. If the flag "abort_if_unrecognized" is true, then this
++// routine will never retun false (zero), but instead will execute a VM panic
++// routine kill the process.
++//
++// If this routine returns false, it is OK to call it again. This allows
++// the user-defined signal handler to perform checks either before or after
++// the VM performs its own checks. Naturally, the user code would be making
++// a serious error if it tried to handle an exception (such as a null check
++// or breakpoint) that the VM was generating for its own correct operation.
++//
++// This routine may recognize any of the following kinds of signals:
++// SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
++// It should be consulted by handlers for any of those signals.
++//
++// The caller of this routine must pass in the three arguments supplied
++// to the function referred to in the "sa_sigaction" (not the "sa_handler")
++// field of the structure passed to sigaction(). This routine assumes that
++// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
++//
++// Note that the VM will print warnings if it detects conflicting signal
++// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
++//
++extern "C" JNIEXPORT int
++JVM_handle_bsd_signal(int signo, siginfo_t* siginfo,
++ void* ucontext, int abort_if_unrecognized);
++
++void signalHandler(int sig, siginfo_t* info, void* uc) {
++ assert(info != NULL && uc != NULL, "it must be old kernel");
++ JVM_handle_bsd_signal(sig, info, uc, true);
++}
++
++
++// This boolean allows users to forward their own non-matching signals
++// to JVM_handle_bsd_signal, harmlessly.
++bool os::Bsd::signal_handlers_are_installed = false;
++
++// For signal-chaining
++struct sigaction os::Bsd::sigact[MAXSIGNUM];
++unsigned int os::Bsd::sigs = 0;
++bool os::Bsd::libjsig_is_loaded = false;
++typedef struct sigaction *(*get_signal_t)(int);
++get_signal_t os::Bsd::get_signal_action = NULL;
++
++struct sigaction* os::Bsd::get_chained_signal_action(int sig) {
++ struct sigaction *actp = NULL;
++
++ if (libjsig_is_loaded) {
++ // Retrieve the old signal handler from libjsig
++ actp = (*get_signal_action)(sig);
++ }
++ if (actp == NULL) {
++ // Retrieve the preinstalled signal handler from jvm
++ actp = get_preinstalled_handler(sig);
++ }
++
++ return actp;
++}
++
++static bool call_chained_handler(struct sigaction *actp, int sig,
++ siginfo_t *siginfo, void *context) {
++ // Call the old signal handler
++ if (actp->sa_handler == SIG_DFL) {
++ // It's more reasonable to let jvm treat it as an unexpected exception
++ // instead of taking the default action.
++ return false;
++ } else if (actp->sa_handler != SIG_IGN) {
++ if ((actp->sa_flags & SA_NODEFER) == 0) {
++ // automaticlly block the signal
++ sigaddset(&(actp->sa_mask), sig);
++ }
++
++ sa_handler_t hand;
++ sa_sigaction_t sa;
++ bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
++ // retrieve the chained handler
++ if (siginfo_flag_set) {
++ sa = actp->sa_sigaction;
++ } else {
++ hand = actp->sa_handler;
++ }
++
++ if ((actp->sa_flags & SA_RESETHAND) != 0) {
++ actp->sa_handler = SIG_DFL;
++ }
++
++ // try to honor the signal mask
++ sigset_t oset;
++ pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
++
++ // call into the chained handler
++ if (siginfo_flag_set) {
++ (*sa)(sig, siginfo, context);
++ } else {
++ (*hand)(sig);
++ }
++
++ // restore the signal mask
++ pthread_sigmask(SIG_SETMASK, &oset, 0);
++ }
++ // Tell jvm's signal handler the signal is taken care of.
++ return true;
++}
++
++bool os::Bsd::chained_handler(int sig, siginfo_t* siginfo, void* context) {
++ bool chained = false;
++ // signal-chaining
++ if (UseSignalChaining) {
++ struct sigaction *actp = get_chained_signal_action(sig);
++ if (actp != NULL) {
++ chained = call_chained_handler(actp, sig, siginfo, context);
++ }
++ }
++ return chained;
++}
++
++struct sigaction* os::Bsd::get_preinstalled_handler(int sig) {
++ if ((( (unsigned int)1 << sig ) & sigs) != 0) {
++ return &sigact[sig];
++ }
++ return NULL;
++}
++
++void os::Bsd::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
++ assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
++ sigact[sig] = oldAct;
++ sigs |= (unsigned int)1 << sig;
++}
++
++// for diagnostic
++int os::Bsd::sigflags[MAXSIGNUM];
++
++int os::Bsd::get_our_sigflags(int sig) {
++ assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
++ return sigflags[sig];
++}
++
++void os::Bsd::set_our_sigflags(int sig, int flags) {
++ assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
++ sigflags[sig] = flags;
++}
++
++void os::Bsd::set_signal_handler(int sig, bool set_installed) {
++ // Check for overwrite.
++ struct sigaction oldAct;
++ sigaction(sig, (struct sigaction*)NULL, &oldAct);
++
++ void* oldhand = oldAct.sa_sigaction
++ ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
++ : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
++ if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
++ oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
++ oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
++ if (AllowUserSignalHandlers || !set_installed) {
++ // Do not overwrite; user takes responsibility to forward to us.
++ return;
++ } else if (UseSignalChaining) {
++ // save the old handler in jvm
++ save_preinstalled_handler(sig, oldAct);
++ // libjsig also interposes the sigaction() call below and saves the
++ // old sigaction on it own.
++ } else {
++ fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
++ "%#lx for signal %d.", (long)oldhand, sig));
++ }
++ }
++
++ struct sigaction sigAct;
++ sigfillset(&(sigAct.sa_mask));
++ sigAct.sa_handler = SIG_DFL;
++ if (!set_installed) {
++ sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
++ } else {
++ sigAct.sa_sigaction = signalHandler;
++ sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
++ }
++ // Save flags, which are set by ours
++ assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
++ sigflags[sig] = sigAct.sa_flags;
++
++ int ret = sigaction(sig, &sigAct, &oldAct);
++ assert(ret == 0, "check");
++
++ void* oldhand2 = oldAct.sa_sigaction
++ ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
++ : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
++ assert(oldhand2 == oldhand, "no concurrent signal handler installation");
++}
++
++// install signal handlers for signals that HotSpot needs to
++// handle in order to support Java-level exception handling.
++
++void os::Bsd::install_signal_handlers() {
++ if (!signal_handlers_are_installed) {
++ signal_handlers_are_installed = true;
++
++ // signal-chaining
++ typedef void (*signal_setting_t)();
++ signal_setting_t begin_signal_setting = NULL;
++ signal_setting_t end_signal_setting = NULL;
++ begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
++ dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
++ if (begin_signal_setting != NULL) {
++ end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
++ dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
++ get_signal_action = CAST_TO_FN_PTR(get_signal_t,
++ dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
++ libjsig_is_loaded = true;
++ assert(UseSignalChaining, "should enable signal-chaining");
++ }
++ if (libjsig_is_loaded) {
++ // Tell libjsig jvm is setting signal handlers
++ (*begin_signal_setting)();
++ }
++
++ set_signal_handler(SIGSEGV, true);
++ set_signal_handler(SIGPIPE, true);
++ set_signal_handler(SIGBUS, true);
++ set_signal_handler(SIGILL, true);
++ set_signal_handler(SIGFPE, true);
++ set_signal_handler(SIGXFSZ, true);
++
++#if defined(__APPLE__)
++ // In Mac OS X 10.4, CrashReporter will write a crash log for all 'fatal' signals, including
++ // signals caught and handled by the JVM. To work around this, we reset the mach task
++ // signal handler that's placed on our process by CrashReporter. This disables
++ // CrashReporter-based reporting.
++ //
++ // This work-around is not necessary for 10.5+, as CrashReporter no longer intercedes
++ // on caught fatal signals.
++ //
++ // Additionally, gdb installs both standard BSD signal handlers, and mach exception
++ // handlers. By replacing the existing task exception handler, we disable gdb's mach
++ // exception handling, while leaving the standard BSD signal handlers functional.
++ kern_return_t kr;
++ kr = task_set_exception_ports(mach_task_self(),
++ EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC,
++ MACH_PORT_NULL,
++ EXCEPTION_STATE_IDENTITY,
++ MACHINE_THREAD_STATE);
++
++ assert(kr == KERN_SUCCESS, "could not set mach task signal handler");
++#endif
++
++ if (libjsig_is_loaded) {
++ // Tell libjsig jvm finishes setting signal handlers
++ (*end_signal_setting)();
++ }
++
++ // We don't activate signal checker if libjsig is in place, we trust ourselves
++ // and if UserSignalHandler is installed all bets are off
++ if (CheckJNICalls) {
++ if (libjsig_is_loaded) {
++ tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
++ check_signals = false;
++ }
++ if (AllowUserSignalHandlers) {
++ tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
++ check_signals = false;
++ }
++ }
++ }
++}
++
++#ifndef _ALLBSD_SOURCE
++// This is the fastest way to get thread cpu time on Bsd.
++// Returns cpu time (user+sys) for any thread, not only for current.
++// POSIX compliant clocks are implemented in the kernels 2.6.16+.
++// It might work on 2.6.10+ with a special kernel/glibc patch.
++// For reference, please, see IEEE Std 1003.1-2004:
++// http://www.unix.org/single_unix_specification
++
++jlong os::Bsd::fast_thread_cpu_time(clockid_t clockid) {
++ struct timespec tp;
++ int rc = os::Bsd::clock_gettime(clockid, &tp);
++ assert(rc == 0, "clock_gettime is expected to return 0 code");
++
++ return (tp.tv_sec * SEC_IN_NANOSECS) + tp.tv_nsec;
++}
++#endif
++
++/////
++// glibc on Bsd platform uses non-documented flag
++// to indicate, that some special sort of signal
++// trampoline is used.
++// We will never set this flag, and we should
++// ignore this flag in our diagnostic
++#ifdef SIGNIFICANT_SIGNAL_MASK
++#undef SIGNIFICANT_SIGNAL_MASK
++#endif
++#define SIGNIFICANT_SIGNAL_MASK (~0x04000000)
++
++static const char* get_signal_handler_name(address handler,
++ char* buf, int buflen) {
++ int offset;
++ bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
++ if (found) {
++ // skip directory names
++ const char *p1, *p2;
++ p1 = buf;
++ size_t len = strlen(os::file_separator());
++ while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
++ jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
++ } else {
++ jio_snprintf(buf, buflen, PTR_FORMAT, handler);
++ }
++ return buf;
++}
++
++static void print_signal_handler(outputStream* st, int sig,
++ char* buf, size_t buflen) {
++ struct sigaction sa;
++
++ sigaction(sig, NULL, &sa);
++
++ // See comment for SIGNIFICANT_SIGNAL_MASK define
++ sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
++
++ st->print("%s: ", os::exception_name(sig, buf, buflen));
++
++ address handler = (sa.sa_flags & SA_SIGINFO)
++ ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
++ : CAST_FROM_FN_PTR(address, sa.sa_handler);
++
++ if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
++ st->print("SIG_DFL");
++ } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
++ st->print("SIG_IGN");
++ } else {
++ st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
++ }
++
++ st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
++
++ address rh = VMError::get_resetted_sighandler(sig);
++ // May be, handler was resetted by VMError?
++ if(rh != NULL) {
++ handler = rh;
++ sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK;
++ }
++
++ st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags);
++
++ // Check: is it our handler?
++ if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||
++ handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) {
++ // It is our signal handler
++ // check for flags, reset system-used one!
++ if((int)sa.sa_flags != os::Bsd::get_our_sigflags(sig)) {
++ st->print(
++ ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
++ os::Bsd::get_our_sigflags(sig));
++ }
++ }
++ st->cr();
++}
++
++
++#define DO_SIGNAL_CHECK(sig) \
++ if (!sigismember(&check_signal_done, sig)) \
++ os::Bsd::check_signal_handler(sig)
++
++// This method is a periodic task to check for misbehaving JNI applications
++// under CheckJNI, we can add any periodic checks here
++
++void os::run_periodic_checks() {
++
++ if (check_signals == false) return;
++
++ // SEGV and BUS if overridden could potentially prevent
++ // generation of hs*.log in the event of a crash, debugging
++ // such a case can be very challenging, so we absolutely
++ // check the following for a good measure:
++ DO_SIGNAL_CHECK(SIGSEGV);
++ DO_SIGNAL_CHECK(SIGILL);
++ DO_SIGNAL_CHECK(SIGFPE);
++ DO_SIGNAL_CHECK(SIGBUS);
++ DO_SIGNAL_CHECK(SIGPIPE);
++ DO_SIGNAL_CHECK(SIGXFSZ);
++
++
++ // ReduceSignalUsage allows the user to override these handlers
++ // see comments at the very top and jvm_solaris.h
++ if (!ReduceSignalUsage) {
++ DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
++ DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
++ DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
++ DO_SIGNAL_CHECK(BREAK_SIGNAL);
++ }
++
++ DO_SIGNAL_CHECK(SR_signum);
++ DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
++}
++
++typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
++
++static os_sigaction_t os_sigaction = NULL;
++
++void os::Bsd::check_signal_handler(int sig) {
++ char buf[O_BUFLEN];
++ address jvmHandler = NULL;
++
++
++ struct sigaction act;
++ if (os_sigaction == NULL) {
++ // only trust the default sigaction, in case it has been interposed
++ os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
++ if (os_sigaction == NULL) return;
++ }
++
++ os_sigaction(sig, (struct sigaction*)NULL, &act);
++
++
++ act.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
++
++ address thisHandler = (act.sa_flags & SA_SIGINFO)
++ ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
++ : CAST_FROM_FN_PTR(address, act.sa_handler) ;
++
++
++ switch(sig) {
++ case SIGSEGV:
++ case SIGBUS:
++ case SIGFPE:
++ case SIGPIPE:
++ case SIGILL:
++ case SIGXFSZ:
++ jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler);
++ break;
++
++ case SHUTDOWN1_SIGNAL:
++ case SHUTDOWN2_SIGNAL:
++ case SHUTDOWN3_SIGNAL:
++ case BREAK_SIGNAL:
++ jvmHandler = (address)user_handler();
++ break;
++
++ case INTERRUPT_SIGNAL:
++ jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
++ break;
++
++ default:
++ if (sig == SR_signum) {
++ jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
++ } else {
++ return;
++ }
++ break;
++ }
++
++ if (thisHandler != jvmHandler) {
++ tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
++ tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
++ tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
++ // No need to check this sig any longer
++ sigaddset(&check_signal_done, sig);
++ } else if(os::Bsd::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Bsd::get_our_sigflags(sig)) {
++ tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
++ tty->print("expected:" PTR32_FORMAT, os::Bsd::get_our_sigflags(sig));
++ tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
++ // No need to check this sig any longer
++ sigaddset(&check_signal_done, sig);
++ }
++
++ // Dump all the signal
++ if (sigismember(&check_signal_done, sig)) {
++ print_signal_handlers(tty, buf, O_BUFLEN);
++ }
++}
++
++extern void report_error(char* file_name, int line_no, char* title, char* format, ...);
++
++extern bool signal_name(int signo, char* buf, size_t len);
++
++const char* os::exception_name(int exception_code, char* buf, size_t size) {
++ if (0 < exception_code && exception_code <= SIGRTMAX) {
++ // signal
++ if (!signal_name(exception_code, buf, size)) {
++ jio_snprintf(buf, size, "SIG%d", exception_code);
++ }
++ return buf;
++ } else {
++ return NULL;
++ }
++}
++
++// this is called _before_ the most of global arguments have been parsed
++void os::init(void) {
++ char dummy; /* used to get a guess on initial stack address */
++// first_hrtime = gethrtime();
++
++ // With BsdThreads the JavaMain thread pid (primordial thread)
++ // is different than the pid of the java launcher thread.
++ // So, on Bsd, the launcher thread pid is passed to the VM
++ // via the sun.java.launcher.pid property.
++ // Use this property instead of getpid() if it was correctly passed.
++ // See bug 6351349.
++ pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
++
++ _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
++
++ clock_tics_per_sec = CLK_TCK;
++
++ init_random(1234567);
++
++ ThreadCritical::initialize();
++
++ Bsd::set_page_size(getpagesize());
++ if (Bsd::page_size() == -1) {
++ fatal(err_msg("os_bsd.cpp: os::init: sysconf failed (%s)",
++ strerror(errno)));
++ }
++ init_page_sizes((size_t) Bsd::page_size());
++
++ Bsd::initialize_system_info();
++
++ // main_thread points to the aboriginal thread
++ Bsd::_main_thread = pthread_self();
++
++ Bsd::clock_init();
++ initial_time_count = os::elapsed_counter();
++
++#ifdef __APPLE__
++ // XXXDARWIN
++ // Work around the unaligned VM callbacks in hotspot's
++ // sharedRuntime. The callbacks don't use SSE2 instructions, and work on
++ // Linux, Solaris, and FreeBSD. On Mac OS X, dyld (rightly so) enforces
++ // alignment when doing symbol lookup. To work around this, we force early
++ // binding of all symbols now, thus binding when alignment is known-good.
++ _dyld_bind_fully_image_containing_address((const void *) &os::init);
++#endif
++}
++
++// To install functions for atexit system call
++extern "C" {
++ static void perfMemory_exit_helper() {
++ perfMemory_exit();
++ }
++}
++
++// this is called _after_ the global arguments have been parsed
++jint os::init_2(void)
++{
++#ifndef _ALLBSD_SOURCE
++ Bsd::fast_thread_clock_init();
++#endif
++
++ // Allocate a single page and mark it as readable for safepoint polling
++ address polling_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
++ guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" );
++
++ os::set_polling_page( polling_page );
++
++#ifndef PRODUCT
++ if(Verbose && PrintMiscellaneous)
++ tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
++#endif
++
++ if (!UseMembar) {
++ address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
++ guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
++ os::set_memory_serialize_page( mem_serialize_page );
++
++#ifndef PRODUCT
++ if(Verbose && PrintMiscellaneous)
++ tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
++#endif
++ }
++
++ os::large_page_init();
++
++ // initialize suspend/resume support - must do this before signal_sets_init()
++ if (SR_initialize() != 0) {
++ perror("SR_initialize failed");
++ return JNI_ERR;
++ }
++
++ Bsd::signal_sets_init();
++ Bsd::install_signal_handlers();
++
++ // Check minimum allowable stack size for thread creation and to initialize
++ // the java system classes, including StackOverflowError - depends on page
++ // size. Add a page for compiler2 recursion in main thread.
++ // Add in 2*BytesPerWord times page size to account for VM stack during
++ // class initialization depending on 32 or 64 bit VM.
++ os::Bsd::min_stack_allowed = MAX2(os::Bsd::min_stack_allowed,
++ (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
++ 2*BytesPerWord COMPILER2_PRESENT(+1)) * Bsd::page_size());
++
++ size_t threadStackSizeInBytes = ThreadStackSize * K;
++ if (threadStackSizeInBytes != 0 &&
++ threadStackSizeInBytes < os::Bsd::min_stack_allowed) {
++ tty->print_cr("\nThe stack size specified is too small, "
++ "Specify at least %dk",
++ os::Bsd::min_stack_allowed/ K);
++ return JNI_ERR;
++ }
++
++ // Make the stack size a multiple of the page size so that
++ // the yellow/red zones can be guarded.
++ JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
++ vm_page_size()));
++
++#ifndef _ALLBSD_SOURCE
++ Bsd::capture_initial_stack(JavaThread::stack_size_at_create());
++
++ Bsd::libpthread_init();
++ if (PrintMiscellaneous && (Verbose || WizardMode)) {
++ tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
++ Bsd::glibc_version(), Bsd::libpthread_version(),
++ Bsd::is_floating_stack() ? "floating stack" : "fixed stack");
++ }
++
++ if (UseNUMA) {
++ if (!Bsd::libnuma_init()) {
++ UseNUMA = false;
++ } else {
++ if ((Bsd::numa_max_node() < 1)) {
++ // There's only one node(they start from 0), disable NUMA.
++ UseNUMA = false;
++ }
++ }
++ // With SHM large pages we cannot uncommit a page, so there's not way
++ // we can make the adaptive lgrp chunk resizing work. If the user specified
++ // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and
++ // disable adaptive resizing.
++ if (UseNUMA && UseLargePages && UseSHM) {
++ if (!FLAG_IS_DEFAULT(UseNUMA)) {
++ if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) {
++ UseLargePages = false;
++ } else {
++ warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing");
++ UseAdaptiveSizePolicy = false;
++ UseAdaptiveNUMAChunkSizing = false;
++ }
++ } else {
++ UseNUMA = false;
++ }
++ }
++ if (!UseNUMA && ForceNUMA) {
++ UseNUMA = true;
++ }
++ }
++#endif
++
++ if (MaxFDLimit) {
++ // set the number of file descriptors to max. print out error
++ // if getrlimit/setrlimit fails but continue regardless.
++ struct rlimit nbr_files;
++ int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
++ if (status != 0) {
++ if (PrintMiscellaneous && (Verbose || WizardMode))
++ perror("os::init_2 getrlimit failed");
++ } else {
++ nbr_files.rlim_cur = nbr_files.rlim_max;
++
++#ifdef __APPLE__
++ // Darwin returns RLIM_INFINITY for rlim_max, but fails with EINVAL if
++ // you attempt to use RLIM_INFINITY. As per setrlimit(2), OPEN_MAX must
++ // be used instead
++ nbr_files.rlim_cur = MIN(OPEN_MAX, nbr_files.rlim_cur);
++#endif
++
++ status = setrlimit(RLIMIT_NOFILE, &nbr_files);
++ if (status != 0) {
++ if (PrintMiscellaneous && (Verbose || WizardMode))
++ perror("os::init_2 setrlimit failed");
++ }
++ }
++ }
++
++#ifndef _ALLBSD_SOURCE
++ // Initialize lock used to serialize thread creation (see os::create_thread)
++ Bsd::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
++#endif
++
++ // at-exit methods are called in the reverse order of their registration.
++ // atexit functions are called on return from main or as a result of a
++ // call to exit(3C). There can be only 32 of these functions registered
++ // and atexit() does not set errno.
++
++ if (PerfAllowAtExitRegistration) {
++ // only register atexit functions if PerfAllowAtExitRegistration is set.
++ // atexit functions can be delayed until process exit time, which
++ // can be problematic for embedded VM situations. Embedded VMs should
++ // call DestroyJavaVM() to assure that VM resources are released.
++
++ // note: perfMemory_exit_helper atexit function may be removed in
++ // the future if the appropriate cleanup code can be added to the
++ // VM_Exit VMOperation's doit method.
++ if (atexit(perfMemory_exit_helper) != 0) {
++ warning("os::init2 atexit(perfMemory_exit_helper) failed");
++ }
++ }
++
++ // initialize thread priority policy
++ prio_init();
++
++ return JNI_OK;
++}
++
++// this is called at the end of vm_initialization
++void os::init_3(void) { }
++
++// Mark the polling page as unreadable
++void os::make_polling_page_unreadable(void) {
++ if( !guard_memory((char*)_polling_page, Bsd::page_size()) )
++ fatal("Could not disable polling page");
++};
++
++// Mark the polling page as readable
++void os::make_polling_page_readable(void) {
++ if( !bsd_mprotect((char *)_polling_page, Bsd::page_size(), PROT_READ)) {
++ fatal("Could not enable polling page");
++ }
++};
++
++int os::active_processor_count() {
++#ifdef _ALLBSD_SOURCE
++ return _processor_count;
++#else
++ // Bsd doesn't yet have a (official) notion of processor sets,
++ // so just return the number of online processors.
++ int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
++ assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
++ return online_cpus;
++#endif
++}
++
++bool os::distribute_processes(uint length, uint* distribution) {
++ // Not yet implemented.
++ return false;
++}
++
++bool os::bind_to_processor(uint processor_id) {
++ // Not yet implemented.
++ return false;
++}
++
++///
++
++// Suspends the target using the signal mechanism and then grabs the PC before
++// resuming the target. Used by the flat-profiler only
++ExtendedPC os::get_thread_pc(Thread* thread) {
++ // Make sure that it is called by the watcher for the VMThread
++ assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
++ assert(thread->is_VM_thread(), "Can only be called for VMThread");
++
++ ExtendedPC epc;
++
++ OSThread* osthread = thread->osthread();
++ if (do_suspend(osthread)) {
++ if (osthread->ucontext() != NULL) {
++ epc = os::Bsd::ucontext_get_pc(osthread->ucontext());
++ } else {
++ // NULL context is unexpected, double-check this is the VMThread
++ guarantee(thread->is_VM_thread(), "can only be called for VMThread");
++ }
++ do_resume(osthread);
++ }
++ // failure means pthread_kill failed for some reason - arguably this is
++ // a fatal problem, but such problems are ignored elsewhere
++
++ return epc;
++}
++
++int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
++{
++#ifdef _ALLBSD_SOURCE
++ return pthread_cond_timedwait(_cond, _mutex, _abstime);
++#else
++ if (is_NPTL()) {
++ return pthread_cond_timedwait(_cond, _mutex, _abstime);
++ } else {
++#ifndef IA64
++ // 6292965: BsdThreads pthread_cond_timedwait() resets FPU control
++ // word back to default 64bit precision if condvar is signaled. Java
++ // wants 53bit precision. Save and restore current value.
++ int fpu = get_fpu_control_word();
++#endif // IA64
++ int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
++#ifndef IA64
++ set_fpu_control_word(fpu);
++#endif // IA64
++ return status;
++ }
++#endif
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// debug support
++
++static address same_page(address x, address y) {
++ int page_bits = -os::vm_page_size();
++ if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
++ return x;
++ else if (x > y)
++ return (address)(intptr_t(y) | ~page_bits) + 1;
++ else
++ return (address)(intptr_t(y) & page_bits);
++}
++
++bool os::find(address addr, outputStream* st) {
++ Dl_info dlinfo;
++ memset(&dlinfo, 0, sizeof(dlinfo));
++ if (dladdr(addr, &dlinfo)) {
++ st->print(PTR_FORMAT ": ", addr);
++ if (dlinfo.dli_sname != NULL) {
++ st->print("%s+%#x", dlinfo.dli_sname,
++ addr - (intptr_t)dlinfo.dli_saddr);
++ } else if (dlinfo.dli_fname) {
++ st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
++ } else {
++ st->print("<absolute address>");
++ }
++ if (dlinfo.dli_fname) {
++ st->print(" in %s", dlinfo.dli_fname);
++ }
++ if (dlinfo.dli_fbase) {
++ st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
++ }
++ st->cr();
++
++ if (Verbose) {
++ // decode some bytes around the PC
++ address begin = same_page(addr-40, addr);
++ address end = same_page(addr+40, addr);
++ address lowest = (address) dlinfo.dli_sname;
++ if (!lowest) lowest = (address) dlinfo.dli_fbase;
++ if (begin < lowest) begin = lowest;
++ Dl_info dlinfo2;
++ if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
++ && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
++ end = (address) dlinfo2.dli_saddr;
++ Disassembler::decode(begin, end, st);
++ }
++ return true;
++ }
++ return false;
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// misc
++
++// This does not do anything on Bsd. This is basically a hook for being
++// able to use structured exception handling (thread-local exception filters)
++// on, e.g., Win32.
++void
++os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
++ JavaCallArguments* args, Thread* thread) {
++ f(value, method, args, thread);
++}
++
++void os::print_statistics() {
++}
++
++int os::message_box(const char* title, const char* message) {
++ int i;
++ fdStream err(defaultStream::error_fd());
++ for (i = 0; i < 78; i++) err.print_raw("=");
++ err.cr();
++ err.print_raw_cr(title);
++ for (i = 0; i < 78; i++) err.print_raw("-");
++ err.cr();
++ err.print_raw_cr(message);
++ for (i = 0; i < 78; i++) err.print_raw("=");
++ err.cr();
++
++ char buf[16];
++ // Prevent process from exiting upon "read error" without consuming all CPU
++ while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
++
++ return buf[0] == 'y' || buf[0] == 'Y';
++}
++
++int os::stat(const char *path, struct stat *sbuf) {
++ char pathbuf[MAX_PATH];
++ if (strlen(path) > MAX_PATH - 1) {
++ errno = ENAMETOOLONG;
++ return -1;
++ }
++ os::native_path(strcpy(pathbuf, path));
++ return ::stat(pathbuf, sbuf);
++}
++
++bool os::check_heap(bool force) {
++ return true;
++}
++
++int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
++ return ::vsnprintf(buf, count, format, args);
++}
++
++// Is a (classpath) directory empty?
++bool os::dir_is_empty(const char* path) {
++ DIR *dir = NULL;
++ struct dirent *ptr;
++
++ dir = opendir(path);
++ if (dir == NULL) return true;
++
++ /* Scan the directory */
++ bool result = true;
++ char buf[sizeof(struct dirent) + MAX_PATH];
++ while (result && (ptr = ::readdir(dir)) != NULL) {
++ if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
++ result = false;
++ }
++ }
++ closedir(dir);
++ return result;
++}
++
++// This code originates from JDK's sysOpen and open64_w
++// from src/solaris/hpi/src/system_md.c
++
++#ifndef O_DELETE
++#define O_DELETE 0x10000
++#endif
++
++// Open a file. Unlink the file immediately after open returns
++// if the specified oflag has the O_DELETE flag set.
++// O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c
++
++int os::open(const char *path, int oflag, int mode) {
++
++ if (strlen(path) > MAX_PATH - 1) {
++ errno = ENAMETOOLONG;
++ return -1;
++ }
++ int fd;
++ int o_delete = (oflag & O_DELETE);
++ oflag = oflag & ~O_DELETE;
++
++ fd = ::open(path, oflag, mode);
++ if (fd == -1) return -1;
++
++ //If the open succeeded, the file might still be a directory
++ {
++ struct stat buf;
++ int ret = ::fstat(fd, &buf);
++ int st_mode = buf.st_mode;
++
++ if (ret != -1) {
++ if ((st_mode & S_IFMT) == S_IFDIR) {
++ errno = EISDIR;
++ ::close(fd);
++ return -1;
++ }
++ } else {
++ ::close(fd);
++ return -1;
++ }
++ }
++
++ /*
++ * All file descriptors that are opened in the JVM and not
++ * specifically destined for a subprocess should have the
++ * close-on-exec flag set. If we don't set it, then careless 3rd
++ * party native code might fork and exec without closing all
++ * appropriate file descriptors (e.g. as we do in closeDescriptors in
++ * UNIXProcess.c), and this in turn might:
++ *
++ * - cause end-of-file to fail to be detected on some file
++ * descriptors, resulting in mysterious hangs, or
++ *
++ * - might cause an fopen in the subprocess to fail on a system
++ * suffering from bug 1085341.
++ *
++ * (Yes, the default setting of the close-on-exec flag is a Unix
++ * design flaw)
++ *
++ * See:
++ * 1085341: 32-bit stdio routines should support file descriptors >255
++ * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
++ * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
++ */
++#ifdef FD_CLOEXEC
++ {
++ int flags = ::fcntl(fd, F_GETFD);
++ if (flags != -1)
++ ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
++ }
++#endif
++
++ if (o_delete != 0) {
++ ::unlink(path);
++ }
++ return fd;
++}
++
++
++// create binary file, rewriting existing file if required
++int os::create_binary_file(const char* path, bool rewrite_existing) {
++ int oflags = O_WRONLY | O_CREAT;
++ if (!rewrite_existing) {
++ oflags |= O_EXCL;
++ }
++ return ::open(path, oflags, S_IREAD | S_IWRITE);
++}
++
++// return current position of file pointer
++jlong os::current_file_offset(int fd) {
++ return (jlong)::lseek(fd, (off_t)0, SEEK_CUR);
++}
++
++// move file pointer to the specified offset
++jlong os::seek_to_file_offset(int fd, jlong offset) {
++ return (jlong)::lseek(fd, (off_t)offset, SEEK_SET);
++}
++
++// This code originates from JDK's sysAvailable
++// from src/solaris/hpi/src/native_threads/src/sys_api_td.c
++
++int os::available(int fd, jlong *bytes) {
++ jlong cur, end;
++ int mode;
++ struct stat buf;
++
++ if (::fstat(fd, &buf) >= 0) {
++ mode = buf.st_mode;
++ if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
++ /*
++ * XXX: is the following call interruptible? If so, this might
++ * need to go through the INTERRUPT_IO() wrapper as for other
++ * blocking, interruptible calls in this file.
++ */
++ int n;
++ if (::ioctl(fd, FIONREAD, &n) >= 0) {
++ *bytes = n;
++ return 1;
++ }
++ }
++ }
++ if ((cur = ::lseek(fd, 0L, SEEK_CUR)) == -1) {
++ return 0;
++ } else if ((end = ::lseek(fd, 0L, SEEK_END)) == -1) {
++ return 0;
++ } else if (::lseek(fd, cur, SEEK_SET) == -1) {
++ return 0;
++ }
++ *bytes = end - cur;
++ return 1;
++}
++
++int os::socket_available(int fd, jint *pbytes) {
++ if (fd < 0)
++ return OS_OK;
++
++ int ret;
++
++ RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret);
++
++ //%% note ioctl can return 0 when successful, JVM_SocketAvailable
++ // is expected to return 0 on failure and 1 on success to the jdk.
++
++ return (ret == OS_ERR) ? 0 : 1;
++}
++
++// Map a block of memory.
++char* os::map_memory(int fd, const char* file_name, size_t file_offset,
++ char *addr, size_t bytes, bool read_only,
++ bool allow_exec) {
++ int prot;
++ int flags;
++
++ if (read_only) {
++ prot = PROT_READ;
++ flags = MAP_SHARED;
++ } else {
++ prot = PROT_READ | PROT_WRITE;
++ flags = MAP_PRIVATE;
++ }
++
++ if (allow_exec) {
++ prot |= PROT_EXEC;
++ }
++
++ if (addr != NULL) {
++ flags |= MAP_FIXED;
++ }
++
++ char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
++ fd, file_offset);
++ if (mapped_address == MAP_FAILED) {
++ return NULL;
++ }
++ return mapped_address;
++}
++
++
++// Remap a block of memory.
++char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
++ char *addr, size_t bytes, bool read_only,
++ bool allow_exec) {
++ // same as map_memory() on this OS
++ return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
++ allow_exec);
++}
++
++
++// Unmap a block of memory.
++bool os::unmap_memory(char* addr, size_t bytes) {
++ return munmap(addr, bytes) == 0;
++}
++
++#ifndef _ALLBSD_SOURCE
++static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
++
++static clockid_t thread_cpu_clockid(Thread* thread) {
++ pthread_t tid = thread->osthread()->pthread_id();
++ clockid_t clockid;
++
++ // Get thread clockid
++ int rc = os::Bsd::pthread_getcpuclockid(tid, &clockid);
++ assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code");
++ return clockid;
++}
++#endif
++
++// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
++// are used by JVM M&M and JVMTI to get user+sys or user CPU time
++// of a thread.
++//
++// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
++// the fast estimate available on the platform.
++
++jlong os::current_thread_cpu_time() {
++#ifdef __APPLE__
++ return os::thread_cpu_time(Thread::current(), true /* user + sys */);
++#elif !defined(_ALLBSD_SOURCE)
++ if (os::Bsd::supports_fast_thread_cpu_time()) {
++ return os::Bsd::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
++ } else {
++ // return user + sys since the cost is the same
++ return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
++ }
++#endif
++}
++
++jlong os::thread_cpu_time(Thread* thread) {
++#ifndef _ALLBSD_SOURCE
++ // consistent with what current_thread_cpu_time() returns
++ if (os::Bsd::supports_fast_thread_cpu_time()) {
++ return os::Bsd::fast_thread_cpu_time(thread_cpu_clockid(thread));
++ } else {
++ return slow_thread_cpu_time(thread, true /* user + sys */);
++ }
++#endif
++}
++
++jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
++#ifdef __APPLE__
++ return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
++#elif !defined(_ALLBSD_SOURCE)
++ if (user_sys_cpu_time && os::Bsd::supports_fast_thread_cpu_time()) {
++ return os::Bsd::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
++ } else {
++ return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
++ }
++#endif
++}
++
++jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
++#ifdef __APPLE__
++ struct thread_basic_info tinfo;
++ mach_msg_type_number_t tcount = THREAD_INFO_MAX;
++ kern_return_t kr;
++ mach_port_t mach_thread;
++
++ mach_thread = pthread_mach_thread_np(thread->osthread()->thread_id());
++ kr = thread_info(mach_thread, THREAD_BASIC_INFO, (thread_info_t)&tinfo, &tcount);
++ if (kr != KERN_SUCCESS)
++ return -1;
++
++ if (user_sys_cpu_time) {
++ jlong nanos;
++ nanos = ((jlong) tinfo.system_time.seconds + tinfo.user_time.seconds) * (jlong)1000000000;
++ nanos += ((jlong) tinfo.system_time.microseconds + (jlong) tinfo.user_time.microseconds) * (jlong)1000;
++ return nanos;
++ } else {
++ return ((jlong)tinfo.user_time.seconds * 1000000000) + ((jlong)tinfo.user_time.microseconds * (jlong)1000);
++ }
++#elif !defined(_ALLBSD_SOURCE)
++ if (user_sys_cpu_time && os::Bsd::supports_fast_thread_cpu_time()) {
++ return os::Bsd::fast_thread_cpu_time(thread_cpu_clockid(thread));
++ } else {
++ return slow_thread_cpu_time(thread, user_sys_cpu_time);
++ }
++#endif
++}
++
++#ifndef _ALLBSD_SOURCE
++//
++// -1 on error.
++//
++
++static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
++ static bool proc_pid_cpu_avail = true;
++ static bool proc_task_unchecked = true;
++ static const char *proc_stat_path = "/proc/%d/stat";
++ pid_t tid = thread->osthread()->thread_id();
++ int i;
++ char *s;
++ char stat[2048];
++ int statlen;
++ char proc_name[64];
++ int count;
++ long sys_time, user_time;
++ char string[64];
++ char cdummy;
++ int idummy;
++ long ldummy;
++ FILE *fp;
++
++ // We first try accessing /proc/<pid>/cpu since this is faster to
++ // process. If this file is not present (bsd kernels 2.5 and above)
++ // then we open /proc/<pid>/stat.
++ if ( proc_pid_cpu_avail ) {
++ sprintf(proc_name, "/proc/%d/cpu", tid);
++ fp = fopen(proc_name, "r");
++ if ( fp != NULL ) {
++ count = fscanf( fp, "%s %lu %lu\n", string, &user_time, &sys_time);
++ fclose(fp);
++ if ( count != 3 ) return -1;
++
++ if (user_sys_cpu_time) {
++ return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
++ } else {
++ return (jlong)user_time * (1000000000 / clock_tics_per_sec);
++ }
++ }
++ else proc_pid_cpu_avail = false;
++ }
++
++ // The /proc/<tid>/stat aggregates per-process usage on
++ // new Bsd kernels 2.6+ where NPTL is supported.
++ // The /proc/self/task/<tid>/stat still has the per-thread usage.
++ // See bug 6328462.
++ // There can be no directory /proc/self/task on kernels 2.4 with NPTL
++ // and possibly in some other cases, so we check its availability.
++ if (proc_task_unchecked && os::Bsd::is_NPTL()) {
++ // This is executed only once
++ proc_task_unchecked = false;
++ fp = fopen("/proc/self/task", "r");
++ if (fp != NULL) {
++ proc_stat_path = "/proc/self/task/%d/stat";
++ fclose(fp);
++ }
++ }
++
++ sprintf(proc_name, proc_stat_path, tid);
++ fp = fopen(proc_name, "r");
++ if ( fp == NULL ) return -1;
++ statlen = fread(stat, 1, 2047, fp);
++ stat[statlen] = '\0';
++ fclose(fp);
++
++ // Skip pid and the command string. Note that we could be dealing with
++ // weird command names, e.g. user could decide to rename java launcher
++ // to "java 1.4.2 :)", then the stat file would look like
++ // 1234 (java 1.4.2 :)) R ... ...
++ // We don't really need to know the command string, just find the last
++ // occurrence of ")" and then start parsing from there. See bug 4726580.
++ s = strrchr(stat, ')');
++ i = 0;
++ if (s == NULL ) return -1;
++
++ // Skip blank chars
++ do s++; while (isspace(*s));
++
++ count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
++ &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
++ &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
++ &user_time, &sys_time);
++ if ( count != 13 ) return -1;
++ if (user_sys_cpu_time) {
++ return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
++ } else {
++ return (jlong)user_time * (1000000000 / clock_tics_per_sec);
++ }
++}
++#endif
++
++void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
++ info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
++ info_ptr->may_skip_backward = false; // elapsed time not wall time
++ info_ptr->may_skip_forward = false; // elapsed time not wall time
++ info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned
++}
++
++void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
++ info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
++ info_ptr->may_skip_backward = false; // elapsed time not wall time
++ info_ptr->may_skip_forward = false; // elapsed time not wall time
++ info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned
++}
++
++bool os::is_thread_cpu_time_supported() {
++#ifdef __APPLE__
++ return true;
++#elif defined(_ALLBSD_SOURCE)
++ return false;
++#else
++ return true;
++#endif
++}
++
++// System loadavg support. Returns -1 if load average cannot be obtained.
++// Bsd doesn't yet have a (official) notion of processor sets,
++// so just return the system wide load average.
++int os::loadavg(double loadavg[], int nelem) {
++ return ::getloadavg(loadavg, nelem);
++}
++
++void os::pause() {
++ char filename[MAX_PATH];
++ if (PauseAtStartupFile && PauseAtStartupFile[0]) {
++ jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
++ } else {
++ jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
++ }
++
++ int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
++ if (fd != -1) {
++ struct stat buf;
++ ::close(fd);
++ while (::stat(filename, &buf) == 0) {
++ (void)::poll(NULL, 0, 100);
++ }
++ } else {
++ jio_fprintf(stderr,
++ "Could not open pause file '%s', continuing immediately.\n", filename);
++ }
++}
++
++
++// Refer to the comments in os_solaris.cpp park-unpark.
++//
++// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
++// hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
++// For specifics regarding the bug see GLIBC BUGID 261237 :
++// http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
++// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
++// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
++// is used. (The simple C test-case provided in the GLIBC bug report manifests the
++// hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
++// and monitorenter when we're using 1-0 locking. All those operations may result in
++// calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version
++// of libpthread avoids the problem, but isn't practical.
++//
++// Possible remedies:
++//
++// 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work.
++// This is palliative and probabilistic, however. If the thread is preempted
++// between the call to compute_abstime() and pthread_cond_timedwait(), more
++// than the minimum period may have passed, and the abstime may be stale (in the
++// past) resultin in a hang. Using this technique reduces the odds of a hang
++// but the JVM is still vulnerable, particularly on heavily loaded systems.
++//
++// 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
++// of the usual flag-condvar-mutex idiom. The write side of the pipe is set
++// NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
++// reduces to poll()+read(). This works well, but consumes 2 FDs per extant
++// thread.
++//
++// 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread
++// that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing
++// a timeout request to the chron thread and then blocking via pthread_cond_wait().
++// This also works well. In fact it avoids kernel-level scalability impediments
++// on certain platforms that don't handle lots of active pthread_cond_timedwait()
++// timers in a graceful fashion.
++//
++// 4. When the abstime value is in the past it appears that control returns
++// correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
++// Subsequent timedwait/wait calls may hang indefinitely. Given that, we
++// can avoid the problem by reinitializing the condvar -- by cond_destroy()
++// followed by cond_init() -- after all calls to pthread_cond_timedwait().
++// It may be possible to avoid reinitialization by checking the return
++// value from pthread_cond_timedwait(). In addition to reinitializing the
++// condvar we must establish the invariant that cond_signal() is only called
++// within critical sections protected by the adjunct mutex. This prevents
++// cond_signal() from "seeing" a condvar that's in the midst of being
++// reinitialized or that is corrupt. Sadly, this invariant obviates the
++// desirable signal-after-unlock optimization that avoids futile context switching.
++//
++// I'm also concerned that some versions of NTPL might allocate an auxilliary
++// structure when a condvar is used or initialized. cond_destroy() would
++// release the helper structure. Our reinitialize-after-timedwait fix
++// put excessive stress on malloc/free and locks protecting the c-heap.
++//
++// We currently use (4). See the WorkAroundNTPLTimedWaitHang flag.
++// It may be possible to refine (4) by checking the kernel and NTPL verisons
++// and only enabling the work-around for vulnerable environments.
++
++// utility to compute the abstime argument to timedwait:
++// millis is the relative timeout time
++// abstime will be the absolute timeout time
++// TODO: replace compute_abstime() with unpackTime()
++
++static struct timespec* compute_abstime(struct timespec* abstime, jlong millis) {
++ if (millis < 0) millis = 0;
++ struct timeval now;
++ int status = gettimeofday(&now, NULL);
++ assert(status == 0, "gettimeofday");
++ jlong seconds = millis / 1000;
++ millis %= 1000;
++ if (seconds > 50000000) { // see man cond_timedwait(3T)
++ seconds = 50000000;
++ }
++ abstime->tv_sec = now.tv_sec + seconds;
++ long usec = now.tv_usec + millis * 1000;
++ if (usec >= 1000000) {
++ abstime->tv_sec += 1;
++ usec -= 1000000;
++ }
++ abstime->tv_nsec = usec * 1000;
++ return abstime;
++}
++
++
++// Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
++// Conceptually TryPark() should be equivalent to park(0).
++
++int os::PlatformEvent::TryPark() {
++ for (;;) {
++ const int v = _Event ;
++ guarantee ((v == 0) || (v == 1), "invariant") ;
++ if (Atomic::cmpxchg (0, &_Event, v) == v) return v ;
++ }
++}
++
++void os::PlatformEvent::park() { // AKA "down()"
++ // Invariant: Only the thread associated with the Event/PlatformEvent
++ // may call park().
++ // TODO: assert that _Assoc != NULL or _Assoc == Self
++ int v ;
++ for (;;) {
++ v = _Event ;
++ if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
++ }
++ guarantee (v >= 0, "invariant") ;
++ if (v == 0) {
++ // Do this the hard way by blocking ...
++ int status = pthread_mutex_lock(_mutex);
++ assert_status(status == 0, status, "mutex_lock");
++ guarantee (_nParked == 0, "invariant") ;
++ ++ _nParked ;
++ while (_Event < 0) {
++ status = pthread_cond_wait(_cond, _mutex);
++ // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
++ // Treat this the same as if the wait was interrupted
++ if (status == ETIMEDOUT) { status = EINTR; }
++ assert_status(status == 0 || status == EINTR, status, "cond_wait");
++ }
++ -- _nParked ;
++
++ // In theory we could move the ST of 0 into _Event past the unlock(),
++ // but then we'd need a MEMBAR after the ST.
++ _Event = 0 ;
++ status = pthread_mutex_unlock(_mutex);
++ assert_status(status == 0, status, "mutex_unlock");
++ }
++ guarantee (_Event >= 0, "invariant") ;
++}
++
++int os::PlatformEvent::park(jlong millis) {
++ guarantee (_nParked == 0, "invariant") ;
++
++ int v ;
++ for (;;) {
++ v = _Event ;
++ if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
++ }
++ guarantee (v >= 0, "invariant") ;
++ if (v != 0) return OS_OK ;
++
++ // We do this the hard way, by blocking the thread.
++ // Consider enforcing a minimum timeout value.
++ struct timespec abst;
++ compute_abstime(&abst, millis);
++
++ int ret = OS_TIMEOUT;
++ int status = pthread_mutex_lock(_mutex);
++ assert_status(status == 0, status, "mutex_lock");
++ guarantee (_nParked == 0, "invariant") ;
++ ++_nParked ;
++
++ // Object.wait(timo) will return because of
++ // (a) notification
++ // (b) timeout
++ // (c) thread.interrupt
++ //
++ // Thread.interrupt and object.notify{All} both call Event::set.
++ // That is, we treat thread.interrupt as a special case of notification.
++ // The underlying Solaris implementation, cond_timedwait, admits
++ // spurious/premature wakeups, but the JLS/JVM spec prevents the
++ // JVM from making those visible to Java code. As such, we must
++ // filter out spurious wakeups. We assume all ETIME returns are valid.
++ //
++ // TODO: properly differentiate simultaneous notify+interrupt.
++ // In that case, we should propagate the notify to another waiter.
++
++ while (_Event < 0) {
++ status = os::Bsd::safe_cond_timedwait(_cond, _mutex, &abst);
++ if (status != 0 && WorkAroundNPTLTimedWaitHang) {
++ pthread_cond_destroy (_cond);
++ pthread_cond_init (_cond, NULL) ;
++ }
++ assert_status(status == 0 || status == EINTR ||
++ status == ETIMEDOUT,
++ status, "cond_timedwait");
++ if (!FilterSpuriousWakeups) break ; // previous semantics
++ if (status == ETIMEDOUT) break ;
++ // We consume and ignore EINTR and spurious wakeups.
++ }
++ --_nParked ;
++ if (_Event >= 0) {
++ ret = OS_OK;
++ }
++ _Event = 0 ;
++ status = pthread_mutex_unlock(_mutex);
++ assert_status(status == 0, status, "mutex_unlock");
++ assert (_nParked == 0, "invariant") ;
++ return ret;
++}
++
++void os::PlatformEvent::unpark() {
++ int v, AnyWaiters ;
++ for (;;) {
++ v = _Event ;
++ if (v > 0) {
++ // The LD of _Event could have reordered or be satisfied
++ // by a read-aside from this processor's write buffer.
++ // To avoid problems execute a barrier and then
++ // ratify the value.
++ OrderAccess::fence() ;
++ if (_Event == v) return ;
++ continue ;
++ }
++ if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
++ }
++ if (v < 0) {
++ // Wait for the thread associated with the event to vacate
++ int status = pthread_mutex_lock(_mutex);
++ assert_status(status == 0, status, "mutex_lock");
++ AnyWaiters = _nParked ;
++ assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
++ if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
++ AnyWaiters = 0 ;
++ pthread_cond_signal (_cond);
++ }
++ status = pthread_mutex_unlock(_mutex);
++ assert_status(status == 0, status, "mutex_unlock");
++ if (AnyWaiters != 0) {
++ status = pthread_cond_signal(_cond);
++ assert_status(status == 0, status, "cond_signal");
++ }
++ }
++
++ // Note that we signal() _after dropping the lock for "immortal" Events.
++ // This is safe and avoids a common class of futile wakeups. In rare
++ // circumstances this can cause a thread to return prematurely from
++ // cond_{timed}wait() but the spurious wakeup is benign and the victim will
++ // simply re-test the condition and re-park itself.
++}
++
++
++// JSR166
++// -------------------------------------------------------
++
++/*
++ * The solaris and bsd implementations of park/unpark are fairly
++ * conservative for now, but can be improved. They currently use a
++ * mutex/condvar pair, plus a a count.
++ * Park decrements count if > 0, else does a condvar wait. Unpark
++ * sets count to 1 and signals condvar. Only one thread ever waits
++ * on the condvar. Contention seen when trying to park implies that someone
++ * is unparking you, so don't wait. And spurious returns are fine, so there
++ * is no need to track notifications.
++ */
++
++
++#define NANOSECS_PER_SEC 1000000000
++#define NANOSECS_PER_MILLISEC 1000000
++#define MAX_SECS 100000000
++/*
++ * This code is common to bsd and solaris and will be moved to a
++ * common place in dolphin.
++ *
++ * The passed in time value is either a relative time in nanoseconds
++ * or an absolute time in milliseconds. Either way it has to be unpacked
++ * into suitable seconds and nanoseconds components and stored in the
++ * given timespec structure.
++ * Given time is a 64-bit value and the time_t used in the timespec is only
++ * a signed-32-bit value (except on 64-bit Bsd) we have to watch for
++ * overflow if times way in the future are given. Further on Solaris versions
++ * prior to 10 there is a restriction (see cond_timedwait) that the specified
++ * number of seconds, in abstime, is less than current_time + 100,000,000.
++ * As it will be 28 years before "now + 100000000" will overflow we can
++ * ignore overflow and just impose a hard-limit on seconds using the value
++ * of "now + 100,000,000". This places a limit on the timeout of about 3.17
++ * years from "now".
++ */
++
++static void unpackTime(struct timespec* absTime, bool isAbsolute, jlong time) {
++ assert (time > 0, "convertTime");
++
++ struct timeval now;
++ int status = gettimeofday(&now, NULL);
++ assert(status == 0, "gettimeofday");
++
++ time_t max_secs = now.tv_sec + MAX_SECS;
++
++ if (isAbsolute) {
++ jlong secs = time / 1000;
++ if (secs > max_secs) {
++ absTime->tv_sec = max_secs;
++ }
++ else {
++ absTime->tv_sec = secs;
++ }
++ absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
++ }
++ else {
++ jlong secs = time / NANOSECS_PER_SEC;
++ if (secs >= MAX_SECS) {
++ absTime->tv_sec = max_secs;
++ absTime->tv_nsec = 0;
++ }
++ else {
++ absTime->tv_sec = now.tv_sec + secs;
++ absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
++ if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
++ absTime->tv_nsec -= NANOSECS_PER_SEC;
++ ++absTime->tv_sec; // note: this must be <= max_secs
++ }
++ }
++ }
++ assert(absTime->tv_sec >= 0, "tv_sec < 0");
++ assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
++ assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
++ assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
++}
++
++void Parker::park(bool isAbsolute, jlong time) {
++ // Optional fast-path check:
++ // Return immediately if a permit is available.
++ if (_counter > 0) {
++ _counter = 0 ;
++ OrderAccess::fence();
++ return ;
++ }
++
++ Thread* thread = Thread::current();
++ assert(thread->is_Java_thread(), "Must be JavaThread");
++ JavaThread *jt = (JavaThread *)thread;
++
++ // Optional optimization -- avoid state transitions if there's an interrupt pending.
++ // Check interrupt before trying to wait
++ if (Thread::is_interrupted(thread, false)) {
++ return;
++ }
++
++ // Next, demultiplex/decode time arguments
++ struct timespec absTime;
++ if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
++ return;
++ }
++ if (time > 0) {
++ unpackTime(&absTime, isAbsolute, time);
++ }
++
++
++ // Enter safepoint region
++ // Beware of deadlocks such as 6317397.
++ // The per-thread Parker:: mutex is a classic leaf-lock.
++ // In particular a thread must never block on the Threads_lock while
++ // holding the Parker:: mutex. If safepoints are pending both the
++ // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
++ ThreadBlockInVM tbivm(jt);
++
++ // Don't wait if cannot get lock since interference arises from
++ // unblocking. Also. check interrupt before trying wait
++ if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
++ return;
++ }
++
++ int status ;
++ if (_counter > 0) { // no wait needed
++ _counter = 0;
++ status = pthread_mutex_unlock(_mutex);
++ assert (status == 0, "invariant") ;
++ OrderAccess::fence();
++ return;
++ }
++
++#ifdef ASSERT
++ // Don't catch signals while blocked; let the running threads have the signals.
++ // (This allows a debugger to break into the running thread.)
++ sigset_t oldsigs;
++ sigset_t* allowdebug_blocked = os::Bsd::allowdebug_blocked_signals();
++ pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
++#endif
++
++ OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
++ jt->set_suspend_equivalent();
++ // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
++
++ if (time == 0) {
++ status = pthread_cond_wait (_cond, _mutex) ;
++ } else {
++ status = os::Bsd::safe_cond_timedwait (_cond, _mutex, &absTime) ;
++ if (status != 0 && WorkAroundNPTLTimedWaitHang) {
++ pthread_cond_destroy (_cond) ;
++ pthread_cond_init (_cond, NULL);
++ }
++ }
++ assert_status(status == 0 || status == EINTR ||
++ status == ETIMEDOUT,
++ status, "cond_timedwait");
++
++#ifdef ASSERT
++ pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
++#endif
++
++ _counter = 0 ;
++ status = pthread_mutex_unlock(_mutex) ;
++ assert_status(status == 0, status, "invariant") ;
++ // If externally suspended while waiting, re-suspend
++ if (jt->handle_special_suspend_equivalent_condition()) {
++ jt->java_suspend_self();
++ }
++
++ OrderAccess::fence();
++}
++
++void Parker::unpark() {
++ int s, status ;
++ status = pthread_mutex_lock(_mutex);
++ assert (status == 0, "invariant") ;
++ s = _counter;
++ _counter = 1;
++ if (s < 1) {
++ if (WorkAroundNPTLTimedWaitHang) {
++ status = pthread_cond_signal (_cond) ;
++ assert (status == 0, "invariant") ;
++ status = pthread_mutex_unlock(_mutex);
++ assert (status == 0, "invariant") ;
++ } else {
++ status = pthread_mutex_unlock(_mutex);
++ assert (status == 0, "invariant") ;
++ status = pthread_cond_signal (_cond) ;
++ assert (status == 0, "invariant") ;
++ }
++ } else {
++ pthread_mutex_unlock(_mutex);
++ assert (status == 0, "invariant") ;
++ }
++}
++
++
++/* Darwin has no "environ" in a dynamic library. */
++#ifdef __APPLE__
++#include <crt_externs.h>
++#define environ (*_NSGetEnviron())
++#else
++extern char** environ;
++#endif
++
++// Run the specified command in a separate process. Return its exit value,
++// or -1 on failure (e.g. can't fork a new process).
++// Unlike system(), this function can be called from signal handler. It
++// doesn't block SIGINT et al.
++int os::fork_and_exec(char* cmd) {
++ const char * argv[4] = {"sh", "-c", cmd, NULL};
++
++ // fork() in BsdThreads/NPTL is not async-safe. It needs to run
++ // pthread_atfork handlers and reset pthread library. All we need is a
++ // separate process to execve. Make a direct syscall to fork process.
++ // On IA64 there's no fork syscall, we have to use fork() and hope for
++ // the best...
++ pid_t pid = fork();
++
++ if (pid < 0) {
++ // fork failed
++ return -1;
++
++ } else if (pid == 0) {
++ // child process
++
++ // execve() in BsdThreads will call pthread_kill_other_threads_np()
++ // first to kill every thread on the thread list. Because this list is
++ // not reset by fork() (see notes above), execve() will instead kill
++ // every thread in the parent process. We know this is the only thread
++ // in the new process, so make a system call directly.
++ // IA64 should use normal execve() from glibc to match the glibc fork()
++ // above.
++ execve("/bin/sh", (char* const*)argv, environ);
++
++ // execve failed
++ _exit(-1);
++
++ } else {
++ // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
++ // care about the actual exit code, for now.
++
++ int status;
++
++ // Wait for the child process to exit. This returns immediately if
++ // the child has already exited. */
++ while (waitpid(pid, &status, 0) < 0) {
++ switch (errno) {
++ case ECHILD: return 0;
++ case EINTR: break;
++ default: return -1;
++ }
++ }
++
++ if (WIFEXITED(status)) {
++ // The child exited normally; get its exit code.
++ return WEXITSTATUS(status);
++ } else if (WIFSIGNALED(status)) {
++ // The child exited because of a signal
++ // The best value to return is 0x80 + signal number,
++ // because that is what all Unix shells do, and because
++ // it allows callers to distinguish between process exit and
++ // process death by signal.
++ return 0x80 + WTERMSIG(status);
++ } else {
++ // Unknown exit code; pass it through
++ return status;
++ }
++ }
++}
++
++// is_headless_jre()
++//
++// Test for the existence of libmawt in motif21 or xawt directories
++// in order to report if we are running in a headless jre
++//
++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";
++ char *p;
++
++ // Get path to libjvm.so
++ os::jvm_path(buf, sizeof(buf));
++
++ // Get rid of libjvm.so
++ p = strrchr(buf, '/');
++ if (p == NULL) return false;
++ else *p = '\0';
++
++ // Get rid of client or server
++ p = strrchr(buf, '/');
++ if (p == NULL) return false;
++ else *p = '\0';
++
++ // check xawt/libmawt.so
++ strcpy(libmawtpath, buf);
++ strcat(libmawtpath, xawtstr);
++ if (::stat(libmawtpath, &statbuf) == 0) return false;
++
++ // check motif21/libmawt.so
++ strcpy(libmawtpath, buf);
++ strcat(libmawtpath, motifstr);
++ if (::stat(libmawtpath, &statbuf) == 0) return false;
++
++ return true;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.hpp openjdk/hotspot/src/os/bsd/vm/os_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/os_bsd.hpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,368 @@
++/*
++ * Copyright (c) 1999, 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_BSD_VM_OS_BSD_HPP
++#define OS_BSD_VM_OS_BSD_HPP
++
++// Bsd_OS defines the interface to Bsd operating systems
++
++/* pthread_getattr_np comes with BsdThreads-0.9-7 on RedHat 7.1 */
++typedef int (*pthread_getattr_func_type) (pthread_t, pthread_attr_t *);
++
++#ifdef __APPLE__
++// Mac OS X doesn't support clock_gettime. Stub out the type, it is
++// unused
++typedef int clockid_t;
++#endif
++
++class Bsd {
++ friend class os;
++
++ // For signal-chaining
++#define MAXSIGNUM 32
++ static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions
++ static unsigned int sigs; // mask of signals that have
++ // preinstalled signal handlers
++ static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
++ // __sigaction(), signal() is loaded
++ static struct sigaction *(*get_signal_action)(int);
++ static struct sigaction *get_preinstalled_handler(int);
++ static void save_preinstalled_handler(int, struct sigaction&);
++
++ static void check_signal_handler(int sig);
++
++ // For signal flags diagnostics
++ static int sigflags[MAXSIGNUM];
++
++ static int (*_clock_gettime)(clockid_t, struct timespec *);
++#ifndef _ALLBSD_SOURCE
++ static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
++
++ static address _initial_thread_stack_bottom;
++ static uintptr_t _initial_thread_stack_size;
++
++ static const char *_glibc_version;
++ static const char *_libpthread_version;
++
++ static bool _is_floating_stack;
++ static bool _is_NPTL;
++ static bool _supports_fast_thread_cpu_time;
++#endif
++
++ static GrowableArray<int>* _cpu_to_node;
++
++ protected:
++
++ static julong _physical_memory;
++ static pthread_t _main_thread;
++#ifndef _ALLBSD_SOURCE
++ static Mutex* _createThread_lock;
++#endif
++ static int _page_size;
++
++ static julong available_memory();
++ static julong physical_memory() { return _physical_memory; }
++ static void initialize_system_info();
++
++#ifndef _ALLBSD_SOURCE
++ static void set_glibc_version(const char *s) { _glibc_version = s; }
++ static void set_libpthread_version(const char *s) { _libpthread_version = s; }
++#endif
++
++ static bool supports_variable_stack_size();
++
++#ifndef _ALLBSD_SOURCE
++ static void set_is_NPTL() { _is_NPTL = true; }
++ static void set_is_BsdThreads() { _is_NPTL = false; }
++ static void set_is_floating_stack() { _is_floating_stack = true; }
++#endif
++
++ static void rebuild_cpu_to_node_map();
++ static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
++
++ static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
++
++ public:
++
++ static void init_thread_fpu_state();
++#ifndef _ALLBSD_SOURCE
++ static int get_fpu_control_word();
++ static void set_fpu_control_word(int fpu_control);
++#endif
++ static pthread_t main_thread(void) { return _main_thread; }
++
++#ifndef _ALLBSD_SOURCE
++ // returns kernel thread id (similar to LWP id on Solaris), which can be
++ // used to access /proc
++ static pid_t gettid();
++ static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
++ static Mutex* createThread_lock(void) { return _createThread_lock; }
++#endif
++ static void hotspot_sigmask(Thread* thread);
++
++#ifndef _ALLBSD_SOURCE
++ static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; }
++ static uintptr_t initial_thread_stack_size(void) { return _initial_thread_stack_size; }
++#endif
++ static bool is_initial_thread(void);
++
++ static int page_size(void) { return _page_size; }
++ static void set_page_size(int val) { _page_size = val; }
++
++ static address ucontext_get_pc(ucontext_t* uc);
++ static intptr_t* ucontext_get_sp(ucontext_t* uc);
++ static intptr_t* ucontext_get_fp(ucontext_t* uc);
++
++ // For Analyzer Forte AsyncGetCallTrace profiling support:
++ //
++ // This interface should be declared in os_bsd_i486.hpp, but
++ // that file provides extensions to the os class and not the
++ // Bsd class.
++ static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc,
++ intptr_t** ret_sp, intptr_t** ret_fp);
++
++ // This boolean allows users to forward their own non-matching signals
++ // to JVM_handle_bsd_signal, harmlessly.
++ static bool signal_handlers_are_installed;
++
++ static int get_our_sigflags(int);
++ static void set_our_sigflags(int, int);
++ static void signal_sets_init();
++ static void install_signal_handlers();
++ static void set_signal_handler(int, bool);
++ static bool is_sig_ignored(int sig);
++
++ static sigset_t* unblocked_signals();
++ static sigset_t* vm_signals();
++ static sigset_t* allowdebug_blocked_signals();
++
++ // For signal-chaining
++ static struct sigaction *get_chained_signal_action(int sig);
++ static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
++
++#ifndef _ALLBSD_SOURCE
++ // GNU libc and libpthread version strings
++ static const char *glibc_version() { return _glibc_version; }
++ static const char *libpthread_version() { return _libpthread_version; }
++
++ // NPTL or BsdThreads?
++ static bool is_BsdThreads() { return !_is_NPTL; }
++ static bool is_NPTL() { return _is_NPTL; }
++
++ // NPTL is always floating stack. BsdThreads could be using floating
++ // stack or fixed stack.
++ static bool is_floating_stack() { return _is_floating_stack; }
++
++ static void libpthread_init();
++ static bool libnuma_init();
++ static void* libnuma_dlsym(void* handle, const char* name);
++#endif
++ // Minimum stack size a thread can be created with (allowing
++ // the VM to completely create the thread and enter user code)
++ static size_t min_stack_allowed;
++
++ // Return default stack size or guard size for the specified thread type
++ static size_t default_stack_size(os::ThreadType thr_type);
++ static size_t default_guard_size(os::ThreadType thr_type);
++
++#ifndef _ALLBSD_SOURCE
++ static void capture_initial_stack(size_t max_size);
++
++ // Stack overflow handling
++ static bool manually_expand_stack(JavaThread * t, address addr);
++ static int max_register_window_saves_before_flushing();
++#endif
++
++ // Real-time clock functions
++ static void clock_init(void);
++
++#ifndef _ALLBSD_SOURCE
++ // fast POSIX clocks support
++ static void fast_thread_clock_init(void);
++#endif
++
++ static bool supports_monotonic_clock() {
++ return _clock_gettime != NULL;
++ }
++
++ static int clock_gettime(clockid_t clock_id, struct timespec *tp) {
++ return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;
++ }
++
++#ifndef _ALLBSD_SOURCE
++ static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
++ return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
++ }
++
++ static bool supports_fast_thread_cpu_time() {
++ return _supports_fast_thread_cpu_time;
++ }
++
++ static jlong fast_thread_cpu_time(clockid_t clockid);
++#endif
++
++ // Stack repair handling
++
++ // none present
++
++ // BsdThreads work-around for 6292965
++ static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
++
++
++ // Bsd suspend/resume support - this helper is a shadow of its former
++ // self now that low-level suspension is barely used, and old workarounds
++ // for BsdThreads are no longer needed.
++ class SuspendResume {
++ private:
++ volatile int _suspend_action;
++ // values for suspend_action:
++ #define SR_NONE (0x00)
++ #define SR_SUSPEND (0x01) // suspend request
++ #define SR_CONTINUE (0x02) // resume request
++
++ volatile jint _state;
++ // values for _state: + SR_NONE
++ #define SR_SUSPENDED (0x20)
++ public:
++ SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
++
++ int suspend_action() const { return _suspend_action; }
++ void set_suspend_action(int x) { _suspend_action = x; }
++
++ // atomic updates for _state
++ void set_suspended() {
++ jint temp, temp2;
++ do {
++ temp = _state;
++ temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
++ } while (temp2 != temp);
++ }
++ void clear_suspended() {
++ jint temp, temp2;
++ do {
++ temp = _state;
++ temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
++ } while (temp2 != temp);
++ }
++ bool is_suspended() { return _state & SR_SUSPENDED; }
++
++ #undef SR_SUSPENDED
++ };
++
++private:
++ typedef int (*sched_getcpu_func_t)(void);
++ typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
++ typedef int (*numa_max_node_func_t)(void);
++ typedef int (*numa_available_func_t)(void);
++ typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
++ typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
++
++ static sched_getcpu_func_t _sched_getcpu;
++ static numa_node_to_cpus_func_t _numa_node_to_cpus;
++ static numa_max_node_func_t _numa_max_node;
++ static numa_available_func_t _numa_available;
++ static numa_tonode_memory_func_t _numa_tonode_memory;
++ static numa_interleave_memory_func_t _numa_interleave_memory;
++ static unsigned long* _numa_all_nodes;
++
++ static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
++ static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }
++ static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }
++ static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
++ static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
++ static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
++ static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
++public:
++ static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
++ static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
++ return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1;
++ }
++ static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; }
++ static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; }
++ static int numa_tonode_memory(void *start, size_t size, int node) {
++ return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
++ }
++ static void numa_interleave_memory(void *start, size_t size) {
++ if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
++ _numa_interleave_memory(start, size, _numa_all_nodes);
++ }
++ }
++ static int get_node_by_cpu(int cpu_id);
++};
++
++
++class PlatformEvent : public CHeapObj {
++ private:
++ double CachePad [4] ; // increase odds that _mutex is sole occupant of cache line
++ volatile int _Event ;
++ volatile int _nParked ;
++ pthread_mutex_t _mutex [1] ;
++ pthread_cond_t _cond [1] ;
++ double PostPad [2] ;
++ Thread * _Assoc ;
++
++ public: // TODO-FIXME: make dtor private
++ ~PlatformEvent() { guarantee (0, "invariant") ; }
++
++ public:
++ PlatformEvent() {
++ int status;
++ status = pthread_cond_init (_cond, NULL);
++ assert_status(status == 0, status, "cond_init");
++ status = pthread_mutex_init (_mutex, NULL);
++ assert_status(status == 0, status, "mutex_init");
++ _Event = 0 ;
++ _nParked = 0 ;
++ _Assoc = NULL ;
++ }
++
++ // Use caution with reset() and fired() -- they may require MEMBARs
++ void reset() { _Event = 0 ; }
++ int fired() { return _Event; }
++ void park () ;
++ void unpark () ;
++ int TryPark () ;
++ int park (jlong millis) ;
++ void SetAssociation (Thread * a) { _Assoc = a ; }
++} ;
++
++class PlatformParker : public CHeapObj {
++ protected:
++ pthread_mutex_t _mutex [1] ;
++ pthread_cond_t _cond [1] ;
++
++ public: // TODO-FIXME: make dtor private
++ ~PlatformParker() { guarantee (0, "invariant") ; }
++
++ public:
++ PlatformParker() {
++ int status;
++ status = pthread_cond_init (_cond, NULL);
++ assert_status(status == 0, status, "cond_init");
++ status = pthread_mutex_init (_mutex, NULL);
++ assert_status(status == 0, status, "mutex_init");
++ }
++} ;
++
++#endif // OS_BSD_VM_OS_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.inline.hpp openjdk/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/os_bsd.inline.hpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,302 @@
++/*
++ * Copyright (c) 1999, 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.
++ *
++ */
++
++#ifndef OS_BSD_VM_OS_BSD_INLINE_HPP
++#define OS_BSD_VM_OS_BSD_INLINE_HPP
++
++#include "runtime/atomic.hpp"
++#include "runtime/os.hpp"
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "atomic_bsd_x86.inline.hpp"
++# include "orderAccess_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "atomic_bsd_zero.inline.hpp"
++# include "orderAccess_bsd_zero.inline.hpp"
++#endif
++
++// System includes
++
++#include <unistd.h>
++#include <sys/socket.h>
++#include <sys/poll.h>
++#include <netdb.h>
++
++inline void* os::thread_local_storage_at(int index) {
++ return pthread_getspecific((pthread_key_t)index);
++}
++
++inline const char* os::file_separator() {
++ return "/";
++}
++
++inline const char* os::line_separator() {
++ return "\n";
++}
++
++inline const char* os::path_separator() {
++ return ":";
++}
++
++inline const char* os::jlong_format_specifier() {
++ return "%lld";
++}
++
++inline const char* os::julong_format_specifier() {
++ return "%llu";
++}
++
++// File names are case-sensitive on windows only
++inline int os::file_name_strcmp(const char* s1, const char* s2) {
++ return strcmp(s1, s2);
++}
++
++inline bool os::obsolete_option(const JavaVMOption *option) {
++ return false;
++}
++
++inline bool os::uses_stack_guard_pages() {
++ return true;
++}
++
++inline bool os::allocate_stack_guard_pages() {
++ assert(uses_stack_guard_pages(), "sanity check");
++#if !defined(__FreeBSD__) || __FreeBSD__ < 5
++ // Since FreeBSD 4 uses malloc() for allocating the thread stack
++ // there is no need to do anything extra to allocate the guard pages
++ return false;
++#else
++ // FreeBSD 5+ uses mmap MAP_STACK for allocating the thread stacks.
++ // Must 'allocate' them or guard pages are ignored.
++ return true;
++#endif
++}
++
++
++// On Bsd, reservations are made on a page by page basis, nothing to do.
++inline void os::split_reserved_memory(char *base, size_t size,
++ size_t split, bool realloc) {
++}
++
++
++// Bang the shadow pages if they need to be touched to be mapped.
++inline void os::bang_stack_shadow_pages() {
++}
++
++inline void os::dll_unload(void *lib) {
++ ::dlclose(lib);
++}
++
++inline const int os::default_file_open_flags() { return 0;}
++
++inline DIR* os::opendir(const char* dirname)
++{
++ assert(dirname != NULL, "just checking");
++ return ::opendir(dirname);
++}
++
++inline int os::readdir_buf_size(const char *path)
++{
++ return NAME_MAX + sizeof(dirent) + 1;
++}
++
++inline jlong os::lseek(int fd, jlong offset, int whence) {
++ return (jlong) ::lseek(fd, offset, whence);
++}
++
++inline int os::fsync(int fd) {
++ return ::fsync(fd);
++}
++
++inline char* os::native_path(char *path) {
++ return path;
++}
++
++inline int os::ftruncate(int fd, jlong length) {
++ return ::ftruncate(fd, length);
++}
++
++inline struct dirent* os::readdir(DIR* dirp, dirent *dbuf)
++{
++ dirent* p;
++ int status;
++ assert(dirp != NULL, "just checking");
++
++ // NOTE: Bsd readdir_r (on RH 6.2 and 7.2 at least) is NOT like the POSIX
++ // version. Here is the doc for this function:
++ // http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_262.html
++
++ if((status = ::readdir_r(dirp, dbuf, &p)) != 0) {
++ errno = status;
++ return NULL;
++ } else
++ return p;
++}
++
++inline int os::closedir(DIR *dirp) {
++ assert(dirp != NULL, "argument is NULL");
++ return ::closedir(dirp);
++}
++
++// macros for restartable system calls
++
++#define RESTARTABLE(_cmd, _result) do { \
++ _result = _cmd; \
++ } while(((int)_result == OS_ERR) && (errno == EINTR))
++
++#define RESTARTABLE_RETURN_INT(_cmd) do { \
++ int _result; \
++ RESTARTABLE(_cmd, _result); \
++ return _result; \
++} while(false)
++
++inline bool os::numa_has_static_binding() { return true; }
++inline bool os::numa_has_group_homing() { return false; }
++
++inline size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) {
++ size_t res;
++ RESTARTABLE( (size_t) ::read(fd, buf, (size_t) nBytes), res);
++ return res;
++}
++
++inline size_t os::write(int fd, const void *buf, unsigned int nBytes) {
++ size_t res;
++ RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res);
++ return res;
++}
++
++inline int os::close(int fd) {
++ RESTARTABLE_RETURN_INT(::close(fd));
++}
++
++inline int os::socket_close(int fd) {
++ RESTARTABLE_RETURN_INT(::close(fd));
++}
++
++inline int os::socket(int domain, int type, int protocol) {
++ return ::socket(domain, type, protocol);
++}
++
++inline int os::recv(int fd, char *buf, int nBytes, int flags) {
++ RESTARTABLE_RETURN_INT(::recv(fd, buf, nBytes, (unsigned int) flags));
++}
++
++inline int os::send(int fd, char *buf, int nBytes, int flags) {
++ RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, (unsigned int) flags));
++}
++
++inline int os::raw_send(int fd, char *buf, int nBytes, int flags) {
++ return os::send(fd, buf, nBytes, flags);
++}
++
++inline int os::timeout(int fd, long timeout) {
++ julong prevtime,newtime;
++ struct timeval t;
++
++ gettimeofday(&t, NULL);
++ prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
++
++ for(;;) {
++ struct pollfd pfd;
++
++ pfd.fd = fd;
++ pfd.events = POLLIN | POLLERR;
++
++ int res = ::poll(&pfd, 1, timeout);
++
++ if (res == OS_ERR && errno == EINTR) {
++
++ // On Bsd any value < 0 means "forever"
++
++ if(timeout >= 0) {
++ gettimeofday(&t, NULL);
++ newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
++ timeout -= newtime - prevtime;
++ if(timeout <= 0)
++ return OS_OK;
++ prevtime = newtime;
++ }
++ } else
++ return res;
++ }
++}
++
++inline int os::listen(int fd, int count) {
++ return ::listen(fd, count);
++}
++
++inline int os::connect(int fd, struct sockaddr *him, int len) {
++ RESTARTABLE_RETURN_INT(::connect(fd, him, len));
++}
++
++inline int os::accept(int fd, struct sockaddr *him, int *len) {
++ // This cast is from int to unsigned int on bsd. Since we
++ // only pass the parameter "len" around the vm and don't try to
++ // fetch it's value, this cast is safe for now. The java.net group
++ // may need and want to change this interface someday if socklen_t goes
++ // to 64 bits on some platform that we support.
++
++ // At least OpenBSD and FreeBSD can return EINTR from accept.
++ RESTARTABLE_RETURN_INT(::accept(fd, him, (socklen_t *)len));
++}
++
++inline int os::recvfrom(int fd, char *buf, int nBytes, int flags,
++ sockaddr *from, int *fromlen) {
++ RESTARTABLE_RETURN_INT(::recvfrom(fd, buf, nBytes, (unsigned int) flags, from, (socklen_t *)fromlen));
++}
++
++inline int os::sendto(int fd, char *buf, int len, int flags,
++ struct sockaddr *to, int tolen) {
++ RESTARTABLE_RETURN_INT(::sendto(fd, buf, len, (unsigned int) flags, to, tolen));
++}
++
++inline int os::socket_shutdown(int fd, int howto){
++ return ::shutdown(fd, howto);
++}
++
++inline int os::bind(int fd, struct sockaddr *him, int len){
++ return ::bind(fd, him, len);
++}
++
++inline int os::get_sock_name(int fd, struct sockaddr *him, int *len){
++ return ::getsockname(fd, him, (socklen_t *)len);
++}
++
++inline int os::get_host_name(char* name, int namelen){
++ return ::gethostname(name, namelen);
++}
++
++inline struct hostent* os::get_host_by_name(char* name) {
++ return ::gethostbyname(name);
++}
++inline int os::get_sock_opt(int fd, int level, int optname,
++ char *optval, int* optlen){
++ return ::getsockopt(fd, level, optname, optval, (socklen_t *)optlen);
++}
++
++inline int os::set_sock_opt(int fd, int level, int optname,
++ const char *optval, int optlen){
++ return ::setsockopt(fd, level, optname, optval, optlen);
++}
++#endif // OS_BSD_VM_OS_BSD_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/os_share_bsd.hpp openjdk/hotspot/src/os/bsd/vm/os_share_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/os_share_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/os_share_bsd.hpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 1999, 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_BSD_VM_OS_SHARE_BSD_HPP
++#define OS_BSD_VM_OS_SHARE_BSD_HPP
++
++// misc
++void signalHandler(int, siginfo_t*, ucontext_t*);
++void handle_unexpected_exception(Thread* thread, int sig, siginfo_t* info, address pc, address adjusted_pc);
++#ifndef PRODUCT
++void continue_with_dump(void);
++#endif
++
++#define PROCFILE_LENGTH 128
++
++#endif // OS_BSD_VM_OS_SHARE_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/osThread_bsd.cpp openjdk/hotspot/src/os/bsd/vm/osThread_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/osThread_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/osThread_bsd.cpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 1999, 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.
++ *
++ */
++
++// no precompiled headers
++#include "runtime/atomic.hpp"
++#include "runtime/handles.inline.hpp"
++#include "runtime/mutexLocker.hpp"
++#include "runtime/os.hpp"
++#include "runtime/osThread.hpp"
++#include "runtime/safepoint.hpp"
++#include "runtime/vmThread.hpp"
++#ifdef TARGET_ARCH_x86
++# include "assembler_x86.inline.hpp"
++#endif
++#ifdef TARGET_ARCH_sparc
++# include "assembler_sparc.inline.hpp"
++#endif
++#ifdef TARGET_ARCH_zero
++# include "assembler_zero.inline.hpp"
++#endif
++#ifdef TARGET_ARCH_arm
++# include "assembler_arm.inline.hpp"
++#endif
++#ifdef TARGET_ARCH_ppc
++# include "assembler_ppc.inline.hpp"
++#endif
++
++
++void OSThread::pd_initialize() {
++ assert(this != NULL, "check");
++ _thread_id = NULL;
++ _pthread_id = NULL;
++ _siginfo = NULL;
++ _ucontext = NULL;
++ _expanding_stack = 0;
++ _alt_sig_stack = NULL;
++
++ sigemptyset(&_caller_sigmask);
++
++ _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true);
++ assert(_startThread_lock !=NULL, "check");
++}
++
++void OSThread::pd_destroy() {
++ delete _startThread_lock;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/osThread_bsd.hpp openjdk/hotspot/src/os/bsd/vm/osThread_bsd.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/osThread_bsd.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/osThread_bsd.hpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,165 @@
++/*
++ * Copyright (c) 1999, 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_BSD_VM_OSTHREAD_BSD_HPP
++#define OS_BSD_VM_OSTHREAD_BSD_HPP
++
++ private:
++ int _thread_type;
++
++ public:
++
++ int thread_type() const {
++ return _thread_type;
++ }
++ void set_thread_type(int type) {
++ _thread_type = type;
++ }
++
++ private:
++
++#ifdef _ALLBSD_SOURCE
++ // _thread_id and _pthread_id are the same on BSD
++ // keep both to minimize code divergence in os_bsd.cpp
++ pthread_t _thread_id;
++ pthread_t _pthread_id;
++#else
++ // _thread_id is kernel thread id (similar to LWP id on Solaris). Each
++ // thread has a unique thread_id (BsdThreads or NPTL). It can be used
++ // to access /proc.
++ pid_t _thread_id;
++
++ // _pthread_id is the pthread id, which is used by library calls
++ // (e.g. pthread_kill).
++ pthread_t _pthread_id;
++#endif
++
++ sigset_t _caller_sigmask; // Caller's signal mask
++
++ public:
++
++ // Methods to save/restore caller's signal mask
++ sigset_t caller_sigmask() const { return _caller_sigmask; }
++ void set_caller_sigmask(sigset_t sigmask) { _caller_sigmask = sigmask; }
++
++#ifdef _ALLBSD_SOURCE
++ pthread_t thread_id() const {
++ return _thread_id;
++ }
++#else
++ pid_t thread_id() const {
++ return _thread_id;
++ }
++#endif
++#ifndef PRODUCT
++ // Used for debugging, return a unique integer for each thread.
++ intptr_t thread_identifier() const { return (intptr_t)_pthread_id; }
++#endif
++#ifdef ASSERT
++ // We expect no reposition failures so kill vm if we get one.
++ //
++ bool valid_reposition_failure() {
++ return false;
++ }
++#endif // ASSERT
++#ifdef _ALLBSD_SOURCE
++ void set_thread_id(pthread_t id) {
++ _thread_id = id;
++ }
++#else
++ void set_thread_id(pid_t id) {
++ _thread_id = id;
++ }
++#endif
++ pthread_t pthread_id() const {
++ return _pthread_id;
++ }
++ void set_pthread_id(pthread_t tid) {
++ _pthread_id = tid;
++ }
++
++ // ***************************************************************
++ // suspension support.
++ // ***************************************************************
++
++public:
++ // flags that support signal based suspend/resume on Bsd are in a
++ // separate class to avoid confusion with many flags in OSThread that
++ // are used by VM level suspend/resume.
++ os::Bsd::SuspendResume sr;
++
++ // _ucontext and _siginfo are used by SR_handler() to save thread context,
++ // and they will later be used to walk the stack or reposition thread PC.
++ // If the thread is not suspended in SR_handler() (e.g. self suspend),
++ // the value in _ucontext is meaningless, so we must use the last Java
++ // frame information as the frame. This will mean that for threads
++ // that are parked on a mutex the profiler (and safepoint mechanism)
++ // will see the thread as if it were still in the Java frame. This
++ // not a problem for the profiler since the Java frame is a close
++ // enough result. For the safepoint mechanism when the give it the
++ // Java frame we are not at a point where the safepoint needs the
++ // frame to that accurate (like for a compiled safepoint) since we
++ // should be in a place where we are native and will block ourselves
++ // if we transition.
++private:
++ void* _siginfo;
++ ucontext_t* _ucontext;
++ int _expanding_stack; /* non zero if manually expanding stack */
++ address _alt_sig_stack; /* address of base of alternate signal stack */
++
++public:
++ void* siginfo() const { return _siginfo; }
++ void set_siginfo(void* ptr) { _siginfo = ptr; }
++ ucontext_t* ucontext() const { return _ucontext; }
++ void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; }
++ void set_expanding_stack(void) { _expanding_stack = 1; }
++ void clear_expanding_stack(void) { _expanding_stack = 0; }
++ int expanding_stack(void) { return _expanding_stack; }
++
++ void set_alt_sig_stack(address val) { _alt_sig_stack = val; }
++ address alt_sig_stack(void) { return _alt_sig_stack; }
++
++private:
++ Monitor* _startThread_lock; // sync parent and child in thread creation
++
++public:
++
++ Monitor* startThread_lock() const {
++ return _startThread_lock;
++ }
++
++ // ***************************************************************
++ // Platform dependent initialization and cleanup
++ // ***************************************************************
++
++private:
++
++ void pd_initialize();
++ void pd_destroy();
++
++// Reconciliation History
++// osThread_solaris.hpp 1.24 99/08/27 13:11:54
++// End
++
++#endif // OS_BSD_VM_OSTHREAD_BSD_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp openjdk/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,1041 @@
++/*
++ * Copyright (c) 2001, 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 "precompiled.hpp"
++#include "classfile/vmSymbols.hpp"
++#include "memory/allocation.inline.hpp"
++#include "memory/resourceArea.hpp"
++#include "oops/oop.inline.hpp"
++#include "os_bsd.inline.hpp"
++#include "runtime/handles.inline.hpp"
++#include "runtime/perfMemory.hpp"
++#include "utilities/exceptions.hpp"
++
++// put OS-includes here
++# include <sys/types.h>
++# include <sys/mman.h>
++# include <errno.h>
++# include <stdio.h>
++# include <unistd.h>
++# include <sys/stat.h>
++# include <signal.h>
++# include <pwd.h>
++
++static char* backing_store_file_name = NULL; // name of the backing store
++ // file, if successfully created.
++
++// Standard Memory Implementation Details
++
++// create the PerfData memory region in standard memory.
++//
++static char* create_standard_memory(size_t size) {
++
++ // allocate an aligned chuck of memory
++ char* mapAddress = os::reserve_memory(size);
++
++ if (mapAddress == NULL) {
++ return NULL;
++ }
++
++ // commit memory
++ if (!os::commit_memory(mapAddress, size)) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("Could not commit PerfData memory\n");
++ }
++ os::release_memory(mapAddress, size);
++ return NULL;
++ }
++
++ return mapAddress;
++}
++
++// delete the PerfData memory region
++//
++static void delete_standard_memory(char* addr, size_t size) {
++
++ // there are no persistent external resources to cleanup for standard
++ // memory. since DestroyJavaVM does not support unloading of the JVM,
++ // cleanup of the memory resource is not performed. The memory will be
++ // reclaimed by the OS upon termination of the process.
++ //
++ return;
++}
++
++// save the specified memory region to the given file
++//
++// Note: this function might be called from signal handler (by os::abort()),
++// don't allocate heap memory.
++//
++static void save_memory_to_file(char* addr, size_t size) {
++
++ const char* destfile = PerfMemory::get_perfdata_file_path();
++ assert(destfile[0] != '\0', "invalid PerfData file path");
++
++ int result;
++
++ RESTARTABLE(::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE),
++ result);;
++ if (result == OS_ERR) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("Could not create Perfdata save file: %s: %s\n",
++ destfile, strerror(errno));
++ }
++ } else {
++ int fd = result;
++
++ for (size_t remaining = size; remaining > 0;) {
++
++ RESTARTABLE(::write(fd, addr, remaining), result);
++ if (result == OS_ERR) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("Could not write Perfdata save file: %s: %s\n",
++ destfile, strerror(errno));
++ }
++ break;
++ }
++
++ remaining -= (size_t)result;
++ addr += result;
++ }
++
++ RESTARTABLE(::close(fd), result);
++ if (PrintMiscellaneous && Verbose) {
++ if (result == OS_ERR) {
++ warning("Could not close %s: %s\n", destfile, strerror(errno));
++ }
++ }
++ }
++ FREE_C_HEAP_ARRAY(char, destfile);
++}
++
++
++// Shared Memory Implementation Details
++
++// Note: the solaris and bsd shared memory implementation uses the mmap
++// interface with a backing store file to implement named shared memory.
++// Using the file system as the name space for shared memory allows a
++// common name space to be supported across a variety of platforms. It
++// also provides a name space that Java applications can deal with through
++// simple file apis.
++//
++// The solaris and bsd implementations store the backing store file in
++// a user specific temporary directory located in the /tmp file system,
++// which is always a local file system and is sometimes a RAM based file
++// system.
++
++// return the user specific temporary directory name.
++//
++// the caller is expected to free the allocated memory.
++//
++static char* get_user_tmp_dir(const char* user) {
++
++ const char* tmpdir = os::get_temp_directory();
++ const char* perfdir = PERFDATA_NAME;
++ size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
++ char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
++
++ // construct the path name to user specific tmp directory
++ snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
++
++ return dirname;
++}
++
++// convert the given file name into a process id. if the file
++// does not meet the file naming constraints, return 0.
++//
++static pid_t filename_to_pid(const char* filename) {
++
++ // a filename that doesn't begin with a digit is not a
++ // candidate for conversion.
++ //
++ if (!isdigit(*filename)) {
++ return 0;
++ }
++
++ // check if file name can be converted to an integer without
++ // any leftover characters.
++ //
++ char* remainder = NULL;
++ errno = 0;
++ pid_t pid = (pid_t)strtol(filename, &remainder, 10);
++
++ if (errno != 0) {
++ return 0;
++ }
++
++ // check for left over characters. If any, then the filename is
++ // not a candidate for conversion.
++ //
++ if (remainder != NULL && *remainder != '\0') {
++ return 0;
++ }
++
++ // successful conversion, return the pid
++ return pid;
++}
++
++
++// check if the given path is considered a secure directory for
++// the backing store files. Returns true if the directory exists
++// and is considered a secure location. Returns false if the path
++// is a symbolic link or if an error occurred.
++//
++static bool is_directory_secure(const char* path) {
++ struct stat statbuf;
++ int result = 0;
++
++ RESTARTABLE(::lstat(path, &statbuf), result);
++ if (result == OS_ERR) {
++ return false;
++ }
++
++ // the path exists, now check it's mode
++ if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
++ // the path represents a link or some non-directory file type,
++ // which is not what we expected. declare it insecure.
++ //
++ return false;
++ }
++ else {
++ // we have an existing directory, check if the permissions are safe.
++ //
++ if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
++ // the directory is open for writing and could be subjected
++ // to a symlnk attack. declare it insecure.
++ //
++ return false;
++ }
++ }
++ return true;
++}
++
++
++// return the user name for the given user id
++//
++// the caller is expected to free the allocated memory.
++//
++static char* get_user_name(uid_t uid) {
++
++ struct passwd pwent;
++
++ // determine the max pwbuf size from sysconf, and hardcode
++ // a default if this not available through sysconf.
++ //
++ long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
++ if (bufsize == -1)
++ bufsize = 1024;
++
++ char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize);
++
++ // POSIX interface to getpwuid_r is used on LINUX
++ struct passwd* p;
++ int result = getpwuid_r(uid, &pwent, pwbuf, (size_t)bufsize, &p);
++
++ if (result != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
++ if (PrintMiscellaneous && Verbose) {
++ if (result != 0) {
++ warning("Could not retrieve passwd entry: %s\n",
++ strerror(result));
++ }
++ else if (p == NULL) {
++ // this check is added to protect against an observed problem
++ // with getpwuid_r() on RedHat 9 where getpwuid_r returns 0,
++ // indicating success, but has p == NULL. This was observed when
++ // inserting a file descriptor exhaustion fault prior to the call
++ // getpwuid_r() call. In this case, error is set to the appropriate
++ // error condition, but this is undocumented behavior. This check
++ // is safe under any condition, but the use of errno in the output
++ // message may result in an erroneous message.
++ // Bug Id 89052 was opened with RedHat.
++ //
++ warning("Could not retrieve passwd entry: %s\n",
++ strerror(errno));
++ }
++ else {
++ warning("Could not determine user name: %s\n",
++ p->pw_name == NULL ? "pw_name = NULL" :
++ "pw_name zero length");
++ }
++ }
++ FREE_C_HEAP_ARRAY(char, pwbuf);
++ return NULL;
++ }
++
++ char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1);
++ strcpy(user_name, p->pw_name);
++
++ FREE_C_HEAP_ARRAY(char, pwbuf);
++ return user_name;
++}
++
++// return the name of the user that owns the process identified by vmid.
++//
++// This method uses a slow directory search algorithm to find the backing
++// store file for the specified vmid and returns the user name, as determined
++// by the user name suffix of the hsperfdata_<username> directory name.
++//
++// the caller is expected to free the allocated memory.
++//
++static char* get_user_name_slow(int vmid, TRAPS) {
++
++ // short circuit the directory search if the process doesn't even exist.
++ if (kill(vmid, 0) == OS_ERR) {
++ if (errno == ESRCH) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
++ "Process not found");
++ }
++ else /* EPERM */ {
++ THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
++ }
++ }
++
++ // directory search
++ char* oldest_user = NULL;
++ time_t oldest_ctime = 0;
++
++ const char* tmpdirname = os::get_temp_directory();
++
++ DIR* tmpdirp = os::opendir(tmpdirname);
++
++ if (tmpdirp == NULL) {
++ return NULL;
++ }
++
++ // for each entry in the directory that matches the pattern hsperfdata_*,
++ // open the directory and check if the file for the given vmid exists.
++ // The file with the expected name and the latest creation date is used
++ // to determine the user name for the process id.
++ //
++ struct dirent* dentry;
++ char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
++ errno = 0;
++ while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
++
++ // check if the directory entry is a hsperfdata file
++ if (strncmp(dentry->d_name, PERFDATA_NAME, strlen(PERFDATA_NAME)) != 0) {
++ continue;
++ }
++
++ char* usrdir_name = NEW_C_HEAP_ARRAY(char,
++ strlen(tmpdirname) + strlen(dentry->d_name) + 2);
++ strcpy(usrdir_name, tmpdirname);
++ strcat(usrdir_name, "/");
++ strcat(usrdir_name, dentry->d_name);
++
++ DIR* subdirp = os::opendir(usrdir_name);
++
++ if (subdirp == NULL) {
++ FREE_C_HEAP_ARRAY(char, usrdir_name);
++ continue;
++ }
++
++ // Since we don't create the backing store files in directories
++ // pointed to by symbolic links, we also don't follow them when
++ // looking for the files. We check for a symbolic link after the
++ // call to opendir in order to eliminate a small window where the
++ // symlink can be exploited.
++ //
++ if (!is_directory_secure(usrdir_name)) {
++ FREE_C_HEAP_ARRAY(char, usrdir_name);
++ os::closedir(subdirp);
++ continue;
++ }
++
++ struct dirent* udentry;
++ char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
++ errno = 0;
++ while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
++
++ if (filename_to_pid(udentry->d_name) == vmid) {
++ struct stat statbuf;
++ int result;
++
++ char* filename = NEW_C_HEAP_ARRAY(char,
++ strlen(usrdir_name) + strlen(udentry->d_name) + 2);
++
++ strcpy(filename, usrdir_name);
++ strcat(filename, "/");
++ strcat(filename, udentry->d_name);
++
++ // don't follow symbolic links for the file
++ RESTARTABLE(::lstat(filename, &statbuf), result);
++ if (result == OS_ERR) {
++ FREE_C_HEAP_ARRAY(char, filename);
++ continue;
++ }
++
++ // skip over files that are not regular files.
++ if (!S_ISREG(statbuf.st_mode)) {
++ FREE_C_HEAP_ARRAY(char, filename);
++ continue;
++ }
++
++ // compare and save filename with latest creation time
++ if (statbuf.st_size > 0 && statbuf.st_ctime > oldest_ctime) {
++
++ if (statbuf.st_ctime > oldest_ctime) {
++ char* user = strchr(dentry->d_name, '_') + 1;
++
++ if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
++ oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
++
++ strcpy(oldest_user, user);
++ oldest_ctime = statbuf.st_ctime;
++ }
++ }
++
++ FREE_C_HEAP_ARRAY(char, filename);
++ }
++ }
++ os::closedir(subdirp);
++ FREE_C_HEAP_ARRAY(char, udbuf);
++ FREE_C_HEAP_ARRAY(char, usrdir_name);
++ }
++ os::closedir(tmpdirp);
++ FREE_C_HEAP_ARRAY(char, tdbuf);
++
++ return(oldest_user);
++}
++
++// return the name of the user that owns the JVM indicated by the given vmid.
++//
++static char* get_user_name(int vmid, TRAPS) {
++ return get_user_name_slow(vmid, CHECK_NULL);
++}
++
++// return the file name of the backing store file for the named
++// shared memory region for the given user name and vmid.
++//
++// the caller is expected to free the allocated memory.
++//
++static char* get_sharedmem_filename(const char* dirname, int vmid) {
++
++ // add 2 for the file separator and a null terminator.
++ size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
++
++ char* name = NEW_C_HEAP_ARRAY(char, nbytes);
++ snprintf(name, nbytes, "%s/%d", dirname, vmid);
++
++ return name;
++}
++
++
++// remove file
++//
++// this method removes the file specified by the given path
++//
++static void remove_file(const char* path) {
++
++ int result;
++
++ // if the file is a directory, the following unlink will fail. since
++ // we don't expect to find directories in the user temp directory, we
++ // won't try to handle this situation. even if accidentially or
++ // maliciously planted, the directory's presence won't hurt anything.
++ //
++ RESTARTABLE(::unlink(path), result);
++ if (PrintMiscellaneous && Verbose && result == OS_ERR) {
++ if (errno != ENOENT) {
++ warning("Could not unlink shared memory backing"
++ " store file %s : %s\n", path, strerror(errno));
++ }
++ }
++}
++
++
++// remove file
++//
++// this method removes the file with the given file name in the
++// named directory.
++//
++static void remove_file(const char* dirname, const char* filename) {
++
++ size_t nbytes = strlen(dirname) + strlen(filename) + 2;
++ char* path = NEW_C_HEAP_ARRAY(char, nbytes);
++
++ strcpy(path, dirname);
++ strcat(path, "/");
++ strcat(path, filename);
++
++ remove_file(path);
++
++ FREE_C_HEAP_ARRAY(char, path);
++}
++
++
++// cleanup stale shared memory resources
++//
++// This method attempts to remove all stale shared memory files in
++// the named user temporary directory. It scans the named directory
++// for files matching the pattern ^$[0-9]*$. For each file found, the
++// process id is extracted from the file name and a test is run to
++// determine if the process is alive. If the process is not alive,
++// any stale file resources are removed.
++//
++static void cleanup_sharedmem_resources(const char* dirname) {
++
++ // open the user temp directory
++ DIR* dirp = os::opendir(dirname);
++
++ if (dirp == NULL) {
++ // directory doesn't exist, so there is nothing to cleanup
++ return;
++ }
++
++ if (!is_directory_secure(dirname)) {
++ // the directory is not a secure directory
++ return;
++ }
++
++ // for each entry in the directory that matches the expected file
++ // name pattern, determine if the file resources are stale and if
++ // so, remove the file resources. Note, instrumented HotSpot processes
++ // for this user may start and/or terminate during this search and
++ // remove or create new files in this directory. The behavior of this
++ // loop under these conditions is dependent upon the implementation of
++ // opendir/readdir.
++ //
++ struct dirent* entry;
++ char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
++ errno = 0;
++ while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
++
++ pid_t pid = filename_to_pid(entry->d_name);
++
++ if (pid == 0) {
++
++ if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
++
++ // attempt to remove all unexpected files, except "." and ".."
++ remove_file(dirname, entry->d_name);
++ }
++
++ errno = 0;
++ continue;
++ }
++
++ // we now have a file name that converts to a valid integer
++ // that could represent a process id . if this process id
++ // matches the current process id or the process is not running,
++ // then remove the stale file resources.
++ //
++ // process liveness is detected by sending signal number 0 to
++ // the process id (see kill(2)). if kill determines that the
++ // process does not exist, then the file resources are removed.
++ // if kill determines that that we don't have permission to
++ // signal the process, then the file resources are assumed to
++ // be stale and are removed because the resources for such a
++ // process should be in a different user specific directory.
++ //
++ if ((pid == os::current_process_id()) ||
++ (kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
++
++ remove_file(dirname, entry->d_name);
++ }
++ errno = 0;
++ }
++ os::closedir(dirp);
++ FREE_C_HEAP_ARRAY(char, dbuf);
++}
++
++// make the user specific temporary directory. Returns true if
++// the directory exists and is secure upon return. Returns false
++// if the directory exists but is either a symlink, is otherwise
++// insecure, or if an error occurred.
++//
++static bool make_user_tmp_dir(const char* dirname) {
++
++ // create the directory with 0755 permissions. note that the directory
++ // will be owned by euid::egid, which may not be the same as uid::gid.
++ //
++ if (mkdir(dirname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == OS_ERR) {
++ if (errno == EEXIST) {
++ // The directory already exists and was probably created by another
++ // JVM instance. However, this could also be the result of a
++ // deliberate symlink. Verify that the existing directory is safe.
++ //
++ if (!is_directory_secure(dirname)) {
++ // directory is not secure
++ if (PrintMiscellaneous && Verbose) {
++ warning("%s directory is insecure\n", dirname);
++ }
++ return false;
++ }
++ }
++ else {
++ // we encountered some other failure while attempting
++ // to create the directory
++ //
++ if (PrintMiscellaneous && Verbose) {
++ warning("could not create directory %s: %s\n",
++ dirname, strerror(errno));
++ }
++ return false;
++ }
++ }
++ return true;
++}
++
++// create the shared memory file resources
++//
++// This method creates the shared memory file with the given size
++// This method also creates the user specific temporary directory, if
++// it does not yet exist.
++//
++static int create_sharedmem_resources(const char* dirname, const char* filename, size_t size) {
++
++ // make the user temporary directory
++ if (!make_user_tmp_dir(dirname)) {
++ // could not make/find the directory or the found directory
++ // was not secure
++ return -1;
++ }
++
++ int result;
++
++ RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
++ if (result == OS_ERR) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("could not create file %s: %s\n", filename, strerror(errno));
++ }
++ return -1;
++ }
++
++ // save the file descriptor
++ int fd = result;
++
++ // set the file size
++ RESTARTABLE(::ftruncate(fd, (off_t)size), result);
++ if (result == OS_ERR) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("could not set shared memory file size: %s\n", strerror(errno));
++ }
++ RESTARTABLE(::close(fd), result);
++ return -1;
++ }
++
++ // Verify that we have enough disk space for this file.
++ // We'll get random SIGBUS crashes on memory accesses if
++ // we don't.
++
++ for (size_t seekpos = 0; seekpos < size; seekpos += os::vm_page_size()) {
++ int zero_int = 0;
++ result = (int)os::seek_to_file_offset(fd, (jlong)(seekpos));
++ if (result == -1 ) break;
++ RESTARTABLE(::write(fd, &zero_int, 1), result);
++ if (result != 1) {
++ if (errno == ENOSPC) {
++ warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
++ }
++ break;
++ }
++ }
++
++ if (result != -1) {
++ return fd;
++ } else {
++ RESTARTABLE(::close(fd), result);
++ return -1;
++ }
++}
++
++// open the shared memory file for the given user and vmid. returns
++// the file descriptor for the open file or -1 if the file could not
++// be opened.
++//
++static int open_sharedmem_file(const char* filename, int oflags, TRAPS) {
++
++ // open the file
++ int result;
++ RESTARTABLE(::open(filename, oflags), result);
++ if (result == OS_ERR) {
++ if (errno == ENOENT) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
++ "Process not found");
++ }
++ else if (errno == EACCES) {
++ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
++ "Permission denied");
++ }
++ else {
++ THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
++ }
++ }
++
++ return result;
++}
++
++// create a named shared memory region. returns the address of the
++// memory region on success or NULL on failure. A return value of
++// NULL will ultimately disable the shared memory feature.
++//
++// On Solaris and Bsd, the name space for shared memory objects
++// is the file system name space.
++//
++// A monitoring application attaching to a JVM does not need to know
++// the file system name of the shared memory object. However, it may
++// be convenient for applications to discover the existence of newly
++// created and terminating JVMs by watching the file system name space
++// for files being created or removed.
++//
++static char* mmap_create_shared(size_t size) {
++
++ int result;
++ int fd;
++ char* mapAddress;
++
++ int vmid = os::current_process_id();
++
++ char* user_name = get_user_name(geteuid());
++
++ if (user_name == NULL)
++ return NULL;
++
++ char* dirname = get_user_tmp_dir(user_name);
++ char* filename = get_sharedmem_filename(dirname, vmid);
++
++ // cleanup any stale shared memory files
++ cleanup_sharedmem_resources(dirname);
++
++ assert(((size > 0) && (size % os::vm_page_size() == 0)),
++ "unexpected PerfMemory region size");
++
++ fd = create_sharedmem_resources(dirname, filename, size);
++
++ FREE_C_HEAP_ARRAY(char, user_name);
++ FREE_C_HEAP_ARRAY(char, dirname);
++
++ if (fd == -1) {
++ FREE_C_HEAP_ARRAY(char, filename);
++ return NULL;
++ }
++
++ mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
++
++ // attempt to close the file - restart it if it was interrupted,
++ // but ignore other failures
++ RESTARTABLE(::close(fd), result);
++ assert(result != OS_ERR, "could not close file");
++
++ if (mapAddress == MAP_FAILED) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("mmap failed - %s\n", strerror(errno));
++ }
++ remove_file(filename);
++ FREE_C_HEAP_ARRAY(char, filename);
++ return NULL;
++ }
++
++ // save the file name for use in delete_shared_memory()
++ backing_store_file_name = filename;
++
++ // clear the shared memory region
++ (void)::memset((void*) mapAddress, 0, size);
++
++ return mapAddress;
++}
++
++// release a named shared memory region
++//
++static void unmap_shared(char* addr, size_t bytes) {
++ os::release_memory(addr, bytes);
++}
++
++// create the PerfData memory region in shared memory.
++//
++static char* create_shared_memory(size_t size) {
++
++ // create the shared memory region.
++ return mmap_create_shared(size);
++}
++
++// delete the shared PerfData memory region
++//
++static void delete_shared_memory(char* addr, size_t size) {
++
++ // cleanup the persistent shared memory resources. since DestroyJavaVM does
++ // not support unloading of the JVM, unmapping of the memory resource is
++ // not performed. The memory will be reclaimed by the OS upon termination of
++ // the process. The backing store file is deleted from the file system.
++
++ assert(!PerfDisableSharedMem, "shouldn't be here");
++
++ if (backing_store_file_name != NULL) {
++ remove_file(backing_store_file_name);
++ // Don't.. Free heap memory could deadlock os::abort() if it is called
++ // from signal handler. OS will reclaim the heap memory.
++ // FREE_C_HEAP_ARRAY(char, backing_store_file_name);
++ backing_store_file_name = NULL;
++ }
++}
++
++// return the size of the file for the given file descriptor
++// or 0 if it is not a valid size for a shared memory file
++//
++static size_t sharedmem_filesize(int fd, TRAPS) {
++
++ struct stat statbuf;
++ int result;
++
++ RESTARTABLE(::fstat(fd, &statbuf), result);
++ if (result == OS_ERR) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("fstat failed: %s\n", strerror(errno));
++ }
++ THROW_MSG_0(vmSymbols::java_io_IOException(),
++ "Could not determine PerfMemory size");
++ }
++
++ if ((statbuf.st_size == 0) ||
++ ((size_t)statbuf.st_size % os::vm_page_size() != 0)) {
++ THROW_MSG_0(vmSymbols::java_lang_Exception(),
++ "Invalid PerfMemory size");
++ }
++
++ return (size_t)statbuf.st_size;
++}
++
++// attach to a named shared memory region.
++//
++static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemoryMode mode, char** addr, size_t* sizep, TRAPS) {
++
++ char* mapAddress;
++ int result;
++ int fd;
++ size_t size;
++ const char* luser = NULL;
++
++ int mmap_prot;
++ int file_flags;
++
++ ResourceMark rm;
++
++ // map the high level access mode to the appropriate permission
++ // constructs for the file and the shared memory mapping.
++ if (mode == PerfMemory::PERF_MODE_RO) {
++ mmap_prot = PROT_READ;
++ file_flags = O_RDONLY;
++ }
++ else if (mode == PerfMemory::PERF_MODE_RW) {
++#ifdef LATER
++ mmap_prot = PROT_READ | PROT_WRITE;
++ file_flags = O_RDWR;
++#else
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
++ "Unsupported access mode");
++#endif
++ }
++ else {
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
++ "Illegal access mode");
++ }
++
++ if (user == NULL || strlen(user) == 0) {
++ luser = get_user_name(vmid, CHECK);
++ }
++ else {
++ luser = user;
++ }
++
++ if (luser == NULL) {
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
++ "Could not map vmid to user Name");
++ }
++
++ char* dirname = get_user_tmp_dir(luser);
++
++ // since we don't follow symbolic links when creating the backing
++ // store file, we don't follow them when attaching either.
++ //
++ if (!is_directory_secure(dirname)) {
++ FREE_C_HEAP_ARRAY(char, dirname);
++ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
++ "Process not found");
++ }
++
++ char* filename = get_sharedmem_filename(dirname, vmid);
++
++ // copy heap memory to resource memory. the open_sharedmem_file
++ // method below need to use the filename, but could throw an
++ // exception. using a resource array prevents the leak that
++ // would otherwise occur.
++ char* rfilename = NEW_RESOURCE_ARRAY(char, strlen(filename) + 1);
++ strcpy(rfilename, filename);
++
++ // free the c heap resources that are no longer needed
++ if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
++ FREE_C_HEAP_ARRAY(char, dirname);
++ FREE_C_HEAP_ARRAY(char, filename);
++
++ // open the shared memory file for the give vmid
++ fd = open_sharedmem_file(rfilename, file_flags, CHECK);
++ assert(fd != OS_ERR, "unexpected value");
++
++ if (*sizep == 0) {
++ size = sharedmem_filesize(fd, CHECK);
++ assert(size != 0, "unexpected size");
++ }
++
++ mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
++
++ // attempt to close the file - restart if it gets interrupted,
++ // but ignore other failures
++ RESTARTABLE(::close(fd), result);
++ assert(result != OS_ERR, "could not close file");
++
++ if (mapAddress == MAP_FAILED) {
++ if (PrintMiscellaneous && Verbose) {
++ warning("mmap failed: %s\n", strerror(errno));
++ }
++ THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
++ "Could not map PerfMemory");
++ }
++
++ *addr = mapAddress;
++ *sizep = size;
++
++ if (PerfTraceMemOps) {
++ tty->print("mapped " SIZE_FORMAT " bytes for vmid %d at "
++ INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress);
++ }
++}
++
++
++
++
++// create the PerfData memory region
++//
++// This method creates the memory region used to store performance
++// data for the JVM. The memory may be created in standard or
++// shared memory.
++//
++void PerfMemory::create_memory_region(size_t size) {
++
++ if (PerfDisableSharedMem) {
++ // do not share the memory for the performance data.
++ _start = create_standard_memory(size);
++ }
++ else {
++ _start = create_shared_memory(size);
++ if (_start == NULL) {
++
++ // creation of the shared memory region failed, attempt
++ // to create a contiguous, non-shared memory region instead.
++ //
++ if (PrintMiscellaneous && Verbose) {
++ warning("Reverting to non-shared PerfMemory region.\n");
++ }
++ PerfDisableSharedMem = true;
++ _start = create_standard_memory(size);
++ }
++ }
++
++ if (_start != NULL) _capacity = size;
++
++}
++
++// delete the PerfData memory region
++//
++// This method deletes the memory region used to store performance
++// data for the JVM. The memory region indicated by the <address, size>
++// tuple will be inaccessible after a call to this method.
++//
++void PerfMemory::delete_memory_region() {
++
++ assert((start() != NULL && capacity() > 0), "verify proper state");
++
++ // If user specifies PerfDataSaveFile, it will save the performance data
++ // to the specified file name no matter whether PerfDataSaveToFile is specified
++ // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag
++ // -XX:+PerfDataSaveToFile.
++ if (PerfDataSaveToFile || PerfDataSaveFile != NULL) {
++ save_memory_to_file(start(), capacity());
++ }
++
++ if (PerfDisableSharedMem) {
++ delete_standard_memory(start(), capacity());
++ }
++ else {
++ delete_shared_memory(start(), capacity());
++ }
++}
++
++// attach to the PerfData memory region for another JVM
++//
++// This method returns an <address, size> tuple that points to
++// a memory buffer that is kept reasonably synchronized with
++// the PerfData memory region for the indicated JVM. This
++// buffer may be kept in synchronization via shared memory
++// or some other mechanism that keeps the buffer updated.
++//
++// If the JVM chooses not to support the attachability feature,
++// this method should throw an UnsupportedOperation exception.
++//
++// This implementation utilizes named shared memory to map
++// the indicated process's PerfData memory region into this JVMs
++// address space.
++//
++void PerfMemory::attach(const char* user, int vmid, PerfMemoryMode mode, char** addrp, size_t* sizep, TRAPS) {
++
++ if (vmid == 0 || vmid == os::current_process_id()) {
++ *addrp = start();
++ *sizep = capacity();
++ return;
++ }
++
++ mmap_attach_shared(user, vmid, mode, addrp, sizep, CHECK);
++}
++
++// detach from the PerfData memory region of another JVM
++//
++// This method detaches the PerfData memory region of another
++// JVM, specified as an <address, size> tuple of a buffer
++// in this process's address space. This method may perform
++// arbitrary actions to accomplish the detachment. The memory
++// region specified by <address, size> will be inaccessible after
++// a call to this method.
++//
++// If the JVM chooses not to support the attachability feature,
++// this method should throw an UnsupportedOperation exception.
++//
++// This implementation utilizes named shared memory to detach
++// the indicated process's PerfData memory region from this
++// process's address space.
++//
++void PerfMemory::detach(char* addr, size_t bytes, TRAPS) {
++
++ assert(addr != 0, "address sanity check");
++ assert(bytes > 0, "capacity sanity check");
++
++ if (PerfMemory::contains(addr) || PerfMemory::contains(addr + bytes - 1)) {
++ // prevent accidental detachment of this process's PerfMemory region
++ return;
++ }
++
++ unmap_shared(addr, bytes);
++}
++
++char* PerfMemory::backing_store_filename() {
++ return backing_store_file_name;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/stubRoutines_bsd.cpp openjdk/hotspot/src/os/bsd/vm/stubRoutines_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/stubRoutines_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/stubRoutines_bsd.cpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (c) 2001, 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 "precompiled.hpp"
++#include "runtime/os.hpp"
++#include "runtime/stubRoutines.hpp"
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp openjdk/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/thread_bsd.inline.hpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2002, 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.
++ *
++ */
++
++#ifndef OS_BSD_VM_THREAD_BSD_INLINE_HPP
++#define OS_BSD_VM_THREAD_BSD_INLINE_HPP
++
++#include "runtime/atomic.hpp"
++#include "runtime/prefetch.hpp"
++#include "runtime/thread.hpp"
++#include "runtime/threadLocalStorage.hpp"
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "atomic_bsd_x86.inline.hpp"
++# include "orderAccess_bsd_x86.inline.hpp"
++# include "prefetch_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "atomic_bsd_zero.inline.hpp"
++# include "orderAccess_bsd_zero.inline.hpp"
++# include "prefetch_bsd_zero.inline.hpp"
++#endif
++
++// Contains inlined functions for class Thread and ThreadLocalStorage
++
++inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
++
++#endif // OS_BSD_VM_THREAD_BSD_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/threadCritical_bsd.cpp openjdk/hotspot/src/os/bsd/vm/threadCritical_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/threadCritical_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/threadCritical_bsd.cpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 2001, 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 "precompiled.hpp"
++#include "runtime/threadCritical.hpp"
++#include "thread_bsd.inline.hpp"
++
++// put OS-includes here
++# include <pthread.h>
++
++//
++// See threadCritical.hpp for details of this class.
++//
++
++static pthread_t tc_owner = 0;
++static pthread_mutex_t tc_mutex = PTHREAD_MUTEX_INITIALIZER;
++static int tc_count = 0;
++
++void ThreadCritical::initialize() {
++}
++
++void ThreadCritical::release() {
++}
++
++ThreadCritical::ThreadCritical() {
++ pthread_t self = pthread_self();
++ if (self != tc_owner) {
++ int ret = pthread_mutex_lock(&tc_mutex);
++ guarantee(ret == 0, "fatal error with pthread_mutex_lock()");
++ assert(tc_count == 0, "Lock acquired with illegal reentry count.");
++ tc_owner = self;
++ }
++ tc_count++;
++}
++
++ThreadCritical::~ThreadCritical() {
++ assert(tc_owner == pthread_self(), "must have correct owner");
++ assert(tc_count > 0, "must have correct count");
++
++ tc_count--;
++ if (tc_count == 0) {
++ tc_owner = 0;
++ int ret = pthread_mutex_unlock(&tc_mutex);
++ guarantee(ret == 0, "fatal error with pthread_mutex_unlock()");
++ }
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/vmError_bsd.cpp openjdk/hotspot/src/os/bsd/vm/vmError_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/vmError_bsd.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/vm/vmError_bsd.cpp 2013-04-08 01:49:33.602321812 +0100
+@@ -0,0 +1,115 @@
++/*
++ * 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 "precompiled.hpp"
++#include "runtime/arguments.hpp"
++#include "runtime/os.hpp"
++#include "runtime/thread.hpp"
++#include "utilities/vmError.hpp"
++
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++#include <signal.h>
++
++void VMError::show_message_box(char *buf, int buflen) {
++ bool yes;
++ do {
++ error_string(buf, buflen);
++ int len = (int)strlen(buf);
++ char *p = &buf[len];
++
++ jio_snprintf(p, buflen - len,
++ "\n\n"
++ "Do you want to debug the problem?\n\n"
++ "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"
++ "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
++ "Otherwise, press RETURN to abort...",
++ os::current_process_id(), os::current_process_id(),
++ os::current_thread_id(), os::current_thread_id());
++
++ yes = os::message_box("Unexpected Error", buf);
++
++ if (yes) {
++ // yes, user asked VM to launch debugger
++ jio_snprintf(buf, buflen, "gdb /proc/%d/exe %d",
++ os::current_process_id(), os::current_process_id());
++
++ os::fork_and_exec(buf);
++ yes = false;
++ }
++ } while (yes);
++}
++
++// Space for our "saved" signal flags and handlers
++static int resettedSigflags[2];
++static address resettedSighandler[2];
++
++static void save_signal(int idx, int sig)
++{
++ struct sigaction sa;
++ sigaction(sig, NULL, &sa);
++ resettedSigflags[idx] = sa.sa_flags;
++ resettedSighandler[idx] = (sa.sa_flags & SA_SIGINFO)
++ ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
++ : CAST_FROM_FN_PTR(address, sa.sa_handler);
++}
++
++int VMError::get_resetted_sigflags(int sig) {
++ if(SIGSEGV == sig) {
++ return resettedSigflags[0];
++ } else if(SIGBUS == sig) {
++ return resettedSigflags[1];
++ }
++ return -1;
++}
++
++address VMError::get_resetted_sighandler(int sig) {
++ if(SIGSEGV == sig) {
++ return resettedSighandler[0];
++ } else if(SIGBUS == sig) {
++ return resettedSighandler[1];
++ }
++ return NULL;
++}
++
++static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
++ // unmask current signal
++ sigset_t newset;
++ sigemptyset(&newset);
++ sigaddset(&newset, sig);
++ sigprocmask(SIG_UNBLOCK, &newset, NULL);
++
++ VMError err(NULL, sig, NULL, info, ucVoid);
++ err.report_and_die();
++}
++
++void VMError::reset_signal_handlers() {
++ // Save sigflags for resetted signals
++ save_signal(0, SIGSEGV);
++ save_signal(1, SIGBUS);
++ os::signal(SIGSEGV, CAST_FROM_FN_PTR(void *, crash_handler));
++ os::signal(SIGBUS, CAST_FROM_FN_PTR(void *, crash_handler));
++}
+diff -Nru openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+--- openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp 2013-04-08 01:48:11.805006641 +0100
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2013-04-08 01:49:33.606321876 +0100
+@@ -22,8 +22,6 @@
+ *
+ */
+
+-# define __STDC_FORMAT_MACROS
+-
+ // no precompiled headers
+ #include "classfile/classLoader.hpp"
+ #include "classfile/systemDictionary.hpp"
+diff -Nru openjdk.orig/hotspot/src/os/posix/launcher/java_md.c openjdk/hotspot/src/os/posix/launcher/java_md.c
+--- openjdk.orig/hotspot/src/os/posix/launcher/java_md.c 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/os/posix/launcher/java_md.c 2013-04-08 01:49:33.606321876 +0100
+@@ -41,14 +41,21 @@
+ #include "version_comp.h"
+ #endif
+
+-#ifdef __linux__
++#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+ #include <pthread.h>
+ #else
+ #include <thread.h>
+ #endif
+
++#ifdef __APPLE__
++#define JVM_DLL "libjvm.dylib"
++#define JAVA_DLL "libjava.dylib"
++#define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
++#else
+ #define JVM_DLL "libjvm.so"
+ #define JAVA_DLL "libjava.so"
++#define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
++#endif
+
+ #ifndef GAMMA /* launcher.make defines ARCH */
+ /*
+@@ -423,10 +430,10 @@
+ * If not on Solaris, assume only a single LD_LIBRARY_PATH
+ * variable.
+ */
+- runpath = getenv("LD_LIBRARY_PATH");
++ runpath = getenv(LD_LIBRARY_PATH);
+ #endif /* __sun */
+
+-#ifdef __linux
++#if defined(__linux__)
+ /*
+ * On linux, if a binary is running as sgid or suid, glibc sets
+ * LD_LIBRARY_PATH to the empty string for security purposes. (In
+@@ -442,6 +449,22 @@
+ if((getgid() != getegid()) || (getuid() != geteuid()) ) {
+ return;
+ }
++#elif defined(_ALLBSD_SOURCE)
++ /*
++ * On BSD, if a binary is running as sgid or suid, libc sets
++ * LD_LIBRARY_PATH to the empty string for security purposes. (In
++ * contrast, on Solaris the LD_LIBRARY_PATH variable for a
++ * privileged binary does not lose its settings; but the dynamic
++ * linker does apply more scrutiny to the path.) The launcher uses
++ * the value of LD_LIBRARY_PATH to prevent an exec loop.
++ * Therefore, if we are running sgid or suid, this function's
++ * setting of LD_LIBRARY_PATH will be ineffective and we should
++ * return from the function now. Getting the right libraries to
++ * be found must be handled through other mechanisms.
++ */
++ if(issetugid()) {
++ return;
++ }
+ #endif
+
+ /* runpath contains current effective LD_LIBRARY_PATH setting */
+@@ -450,7 +473,7 @@
+ new_runpath = JLI_MemAlloc( ((runpath!=NULL)?strlen(runpath):0) +
+ 2*strlen(jrepath) + 2*strlen(arch) +
+ strlen(jvmpath) + 52);
+- newpath = new_runpath + strlen("LD_LIBRARY_PATH=");
++ newpath = new_runpath + strlen(LD_LIBRARY_PATH "=");
+
+
+ /*
+@@ -465,7 +488,7 @@
+
+ /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */
+
+- sprintf(new_runpath, "LD_LIBRARY_PATH="
++ sprintf(new_runpath, LD_LIBRARY_PATH "="
+ "%s:"
+ "%s/lib/%s:"
+ "%s/../lib/%s",
+@@ -792,7 +815,7 @@
+ jboolean
+ GetApplicationHome(char *buf, jint bufsize)
+ {
+-#ifdef __linux__
++#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+ char *execname = GetExecname();
+ if (execname) {
+ strncpy(buf, execname, bufsize-1);
+@@ -1175,7 +1198,7 @@
+
+ #endif /* __sun && i586 */
+
+-#if defined(__linux__) && defined(i586)
++#if (defined(__linux__) || defined(_ALLBSD_SOURCE)) && defined(i586)
+
+ /*
+ * A utility method for asking the CPU about itself.
+@@ -1452,6 +1475,39 @@
+
+ #endif /* __linux__ && i586 */
+
++#if defined(_ALLBSD_SOURCE) && defined(i586)
++
++/* The definition of a server-class machine for bsd-i586 */
++jboolean
++bsd_i586_ServerClassMachine(void) {
++ jboolean result = JNI_FALSE;
++ /* How big is a server class machine? */
++ const unsigned long server_processors = 2UL;
++ const uint64_t server_memory = 2UL * GB;
++ /*
++ * We seem not to get our full complement of memory.
++ * We allow some part (1/8?) of the memory to be "missing",
++ * based on the sizes of DIMMs, and maybe graphics cards.
++ */
++ const uint64_t missing_memory = 256UL * MB;
++ const uint64_t actual_memory = physical_memory();
++
++ /* Is this a server class machine? */
++ if (actual_memory >= (server_memory - missing_memory)) {
++ const unsigned long actual_processors = physical_processors();
++ if (actual_processors >= server_processors) {
++ result = JNI_TRUE;
++ }
++ }
++ if (_launcher_debug) {
++ printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n",
++ (result == JNI_TRUE ? "true" : "false"));
++ }
++ return result;
++}
++
++#endif /* _ALLBSD_SOURCE && i586 */
++
+ /* Dispatch to the platform-specific definition of "server-class" */
+ jboolean
+ ServerClassMachine(void) {
+@@ -1466,6 +1522,8 @@
+ result = solaris_i586_ServerClassMachine();
+ #elif defined(__linux__) && defined(i586)
+ result = linux_i586_ServerClassMachine();
++#elif defined(_ALLBSD_SOURCE) && defined(i586)
++ result = bsd_i586_ServerClassMachine();
+ #else
+ if (_launcher_debug) {
+ printf("ServerClassMachine: returns default value of %s\n",
+@@ -1821,7 +1879,7 @@
+ int
+ ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
+ int rslt;
+-#ifdef __linux__
++#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+ pthread_t tid;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+diff -Nru openjdk.orig/hotspot/src/os/posix/launcher/launcher.script openjdk/hotspot/src/os/posix/launcher/launcher.script
+--- openjdk.orig/hotspot/src/os/posix/launcher/launcher.script 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/os/posix/launcher/launcher.script 2013-04-08 01:49:33.606321876 +0100
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+
+ # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,87 @@
++/*
++ * Copyright (c) 1999, 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 "precompiled.hpp"
++#include "asm/assembler.hpp"
++#include "assembler_x86.inline.hpp"
++#include "runtime/os.hpp"
++#include "runtime/threadLocalStorage.hpp"
++
++#ifndef _LP64
++void MacroAssembler::int3() {
++ call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
++}
++
++void MacroAssembler::get_thread(Register thread) {
++ movl(thread, rsp);
++ shrl(thread, PAGE_SHIFT);
++
++ ExternalAddress tls_base((address)ThreadLocalStorage::sp_map_addr());
++ Address index(noreg, thread, Address::times_4);
++ ArrayAddress tls(tls_base, index);
++
++ movptr(thread, tls);
++}
++#else
++void MacroAssembler::int3() {
++ call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
++}
++
++void MacroAssembler::get_thread(Register thread) {
++ // call pthread_getspecific
++ // void * pthread_getspecific(pthread_key_t key);
++ if (thread != rax) {
++ push(rax);
++ }
++ push(rdi);
++ push(rsi);
++ push(rdx);
++ push(rcx);
++ push(r8);
++ push(r9);
++ push(r10);
++ // XXX
++ mov(r10, rsp);
++ andq(rsp, -16);
++ push(r10);
++ push(r11);
++
++ movl(rdi, ThreadLocalStorage::thread_index());
++ call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
++
++ pop(r11);
++ pop(rsp);
++ pop(r10);
++ pop(r9);
++ pop(r8);
++ pop(rcx);
++ pop(rdx);
++ pop(rsi);
++ pop(rdi);
++ if (thread != rax) {
++ mov(thread, rax);
++ pop(rax);
++ }
++}
++#endif
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,221 @@
++/*
++ * Copyright (c) 1999, 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.
++ *
++ */
++
++#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
++#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
++
++#include "orderAccess_bsd_x86.inline.hpp"
++#include "runtime/atomic.hpp"
++#include "runtime/os.hpp"
++#include "vm_version_x86.hpp"
++
++// Implementation of class atomic
++
++inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; }
++inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; }
++inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; }
++inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; }
++inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; }
++
++inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; }
++inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; }
++inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; }
++inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
++inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
++
++
++// Adding a lock prefix to an instruction on MP machine
++#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
++
++inline jint Atomic::add (jint add_value, volatile jint* dest) {
++ jint addend = add_value;
++ int mp = os::is_MP();
++ __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)"
++ : "=r" (addend)
++ : "0" (addend), "r" (dest), "r" (mp)
++ : "cc", "memory");
++ return addend + add_value;
++}
++
++inline void Atomic::inc (volatile jint* dest) {
++ int mp = os::is_MP();
++ __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" :
++ : "r" (dest), "r" (mp) : "cc", "memory");
++}
++
++inline void Atomic::inc_ptr(volatile void* dest) {
++ inc_ptr((volatile intptr_t*)dest);
++}
++
++inline void Atomic::dec (volatile jint* dest) {
++ int mp = os::is_MP();
++ __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" :
++ : "r" (dest), "r" (mp) : "cc", "memory");
++}
++
++inline void Atomic::dec_ptr(volatile void* dest) {
++ dec_ptr((volatile intptr_t*)dest);
++}
++
++inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
++ __asm__ volatile ( "xchgl (%2),%0"
++ : "=r" (exchange_value)
++ : "0" (exchange_value), "r" (dest)
++ : "memory");
++ return exchange_value;
++}
++
++inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
++ return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
++}
++
++
++inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
++ int mp = os::is_MP();
++ __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
++ : "=a" (exchange_value)
++ : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
++ : "cc", "memory");
++ return exchange_value;
++}
++
++#ifdef AMD64
++inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
++inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
++
++inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
++ intptr_t addend = add_value;
++ bool mp = os::is_MP();
++ __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
++ : "=r" (addend)
++ : "0" (addend), "r" (dest), "r" (mp)
++ : "cc", "memory");
++ return addend + add_value;
++}
++
++inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
++ return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
++}
++
++inline void Atomic::inc_ptr(volatile intptr_t* dest) {
++ bool mp = os::is_MP();
++ __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)"
++ :
++ : "r" (dest), "r" (mp)
++ : "cc", "memory");
++}
++
++inline void Atomic::dec_ptr(volatile intptr_t* dest) {
++ bool mp = os::is_MP();
++ __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)"
++ :
++ : "r" (dest), "r" (mp)
++ : "cc", "memory");
++}
++
++inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
++ __asm__ __volatile__ ("xchgq (%2),%0"
++ : "=r" (exchange_value)
++ : "0" (exchange_value), "r" (dest)
++ : "memory");
++ return exchange_value;
++}
++
++inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
++ bool mp = os::is_MP();
++ __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
++ : "=a" (exchange_value)
++ : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
++ : "cc", "memory");
++ return exchange_value;
++}
++
++inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
++ return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value);
++}
++
++inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
++ return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value);
++}
++
++inline jlong Atomic::load(volatile jlong* src) { return *src; }
++
++#else // !AMD64
++
++inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
++ return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest);
++}
++
++inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
++ return (void*)Atomic::add((jint)add_value, (volatile jint*)dest);
++}
++
++
++inline void Atomic::inc_ptr(volatile intptr_t* dest) {
++ inc((volatile jint*)dest);
++}
++
++inline void Atomic::dec_ptr(volatile intptr_t* dest) {
++ dec((volatile jint*)dest);
++}
++
++inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
++ return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest);
++}
++
++extern "C" {
++ // defined in bsd_x86.s
++ jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool);
++ void _Atomic_move_long(volatile jlong* src, volatile jlong* dst);
++}
++
++inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
++ return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP());
++}
++
++inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
++ return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
++}
++
++inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
++ return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
++}
++
++inline jlong Atomic::load(volatile jlong* src) {
++ volatile jlong dest;
++ _Atomic_move_long(src, &dest);
++ return dest;
++}
++
++inline void Atomic::store(jlong store_value, jlong* dest) {
++ _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest);
++}
++
++inline void Atomic::store(jlong store_value, volatile jlong* dest) {
++ _Atomic_move_long((volatile jlong*)&store_value, dest);
++}
++
++#endif // AMD64
++
++#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,160 @@
++//
++// Copyright (c) 1999, 2008, 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.
++//
++//
++
++// X86 Bsd Architecture Description File
++
++//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
++// This block specifies the encoding classes used by the compiler to output
++// byte streams. Encoding classes generate functions which are called by
++// Machine Instruction Nodes in order to generate the bit encoding of the
++// instruction. Operands specify their base encoding interface with the
++// interface keyword. There are currently supported four interfaces,
++// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
++// operand to generate a function which returns its register number when
++// queried. CONST_INTER causes an operand to generate a function which
++// returns the value of the constant when queried. MEMORY_INTER causes an
++// operand to generate four functions which return the Base Register, the
++// Index Register, the Scale Value, and the Offset Value of the operand when
++// queried. COND_INTER causes an operand to generate six functions which
++// return the encoding code (ie - encoding bits for the instruction)
++// associated with each basic boolean condition for a conditional instruction.
++// Instructions specify two basic values for encoding. They use the
++// ins_encode keyword to specify their encoding class (which must be one of
++// the class names specified in the encoding block), and they use the
++// opcode keyword to specify, in order, their primary, secondary, and
++// tertiary opcode. Only the opcode sections which a particular instruction
++// needs for encoding need to be specified.
++encode %{
++ // Build emit functions for each basic byte or larger field in the intel
++ // encoding scheme (opcode, rm, sib, immediate), and call them from C++
++ // code in the enc_class source block. Emit functions will live in the
++ // main source block for now. In future, we can generalize this by
++ // adding a syntax that specifies the sizes of fields in an order,
++ // so that the adlc can build the emit functions automagically
++
++ enc_class bsd_tlsencode (eRegP dst) %{
++ Register dstReg = as_Register($dst$$reg);
++ MacroAssembler* masm = new MacroAssembler(&cbuf);
++ masm->get_thread(dstReg);
++ %}
++
++ enc_class bsd_breakpoint %{
++ MacroAssembler* masm = new MacroAssembler(&cbuf);
++ masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
++ %}
++
++ enc_class call_epilog %{
++ if( VerifyStackAtCalls ) {
++ // Check that stack depth is unchanged: find majik cookie on stack
++ int framesize = ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP,-3*VMRegImpl::slots_per_word));
++ if(framesize >= 128) {
++ emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
++ emit_d8(cbuf,0xBC);
++ emit_d8(cbuf,0x24);
++ emit_d32(cbuf,framesize); // Find majik cookie from ESP
++ emit_d32(cbuf, 0xbadb100d);
++ }
++ else {
++ emit_opcode(cbuf, 0x81); // cmp [esp+0],0xbadb1ood
++ emit_d8(cbuf,0x7C);
++ emit_d8(cbuf,0x24);
++ emit_d8(cbuf,framesize); // Find majik cookie from ESP
++ emit_d32(cbuf, 0xbadb100d);
++ }
++ // jmp EQ around INT3
++ // QQQ TODO
++ const int jump_around = 5; // size of call to breakpoint, 1 for CC
++ emit_opcode(cbuf,0x74);
++ emit_d8(cbuf, jump_around);
++ // QQQ temporary
++ emit_break(cbuf);
++ // Die if stack mismatch
++ // emit_opcode(cbuf,0xCC);
++ }
++ %}
++
++%}
++
++// INSTRUCTIONS -- Platform dependent
++
++//----------OS and Locking Instructions----------------------------------------
++
++// This name is KNOWN by the ADLC and cannot be changed.
++// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
++// for this guy.
++instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
++ match(Set dst (ThreadLocal));
++ effect(DEF dst, KILL cr);
++
++ format %{ "MOV $dst, Thread::current()" %}
++ ins_encode( bsd_tlsencode(dst) );
++ ins_pipe( ialu_reg_fat );
++%}
++
++instruct TLS(eRegP dst) %{
++ match(Set dst (ThreadLocal));
++
++ expand %{
++ tlsLoadP(dst);
++ %}
++%}
++
++// Die now
++instruct ShouldNotReachHere( )
++%{
++ match(Halt);
++
++ // Use the following format syntax
++ format %{ "INT3 ; ShouldNotReachHere" %}
++ // QQQ TODO for now call breakpoint
++ // opcode(0xCC);
++ // ins_encode(Opc);
++ ins_encode(bsd_breakpoint);
++ ins_pipe( pipe_slow );
++%}
++
++
++
++// Platform dependent source
++
++source %{
++
++// emit an interrupt that is caught by the debugger
++void emit_break(CodeBuffer &cbuf) {
++
++ // Debugger doesn't really catch this but best we can do so far QQQ
++ MacroAssembler* masm = new MacroAssembler(&cbuf);
++ masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
++}
++
++void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
++ emit_break(cbuf);
++}
++
++
++uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
++ return 5;
++}
++
++%}
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,689 @@
++#
++# Copyright (c) 2004, 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.
++#
++
++
++#ifdef __APPLE__
++# Darwin uses _ prefixed global symbols
++#define SYMBOL(s) _ ## s
++#define ELF_TYPE(name, description)
++#else
++#define SYMBOL(s) s
++#define ELF_TYPE(name, description) .type name,description
++#endif
++
++ .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.
++
++ .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_conjoint_jints_atomic)
++ .globl SYMBOL(_Copy_arrayof_conjoint_jints)
++ .globl SYMBOL(_Copy_conjoint_jlongs_atomic)
++ .globl SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts)
++
++ .globl SYMBOL(_Atomic_cmpxchg_long)
++ .globl SYMBOL(_Atomic_move_long)
++
++ .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
++
++ .globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
++ .globl SYMBOL(SafeFetchN)
++ ## TODO: avoid exposing Fetch32PFI and Fetch32Resume.
++ ## 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)
++ .p2align 4,,15
++SYMBOL(SafeFetch32):
++SYMBOL(SafeFetchN):
++ movl 0x8(%esp), %eax
++ movl 0x4(%esp), %ecx
++SYMBOL(Fetch32PFI):
++ movl (%ecx), %eax
++SYMBOL(Fetch32Resume):
++ ret
++
++
++ .globl SYMBOL(SpinPause)
++ ELF_TYPE(SpinPause,@function)
++ .p2align 4,,15
++SYMBOL(SpinPause):
++ rep
++ nop
++ movl $1, %eax
++ ret
++
++ # Support for void Copy::conjoint_bytes(void* from,
++ # void* to,
++ # size_t count)
++ .p2align 4,,15
++ ELF_TYPE(_Copy_conjoint_bytes,@function)
++SYMBOL(_Copy_conjoint_bytes):
++ pushl %esi
++ movl 4+12(%esp),%ecx # count
++ pushl %edi
++ movl 8+ 4(%esp),%esi # from
++ movl 8+ 8(%esp),%edi # to
++ cmpl %esi,%edi
++ leal -1(%esi,%ecx),%eax # from + count - 1
++ jbe cb_CopyRight
++ cmpl %eax,%edi
++ jbe cb_CopyLeft
++ # copy from low to high
++cb_CopyRight:
++ cmpl $3,%ecx
++ jbe 5f # <= 3 bytes
++ # align source address at dword address boundary
++ movl %ecx,%eax # original count
++ movl $4,%ecx
++ subl %esi,%ecx
++ andl $3,%ecx # prefix byte count
++ jz 1f # no prefix
++ subl %ecx,%eax # byte count less prefix
++ # copy prefix
++ subl %esi,%edi
++0: movb (%esi),%dl
++ movb %dl,(%edi,%esi,1)
++ addl $1,%esi
++ subl $1,%ecx
++ jnz 0b
++ addl %esi,%edi
++1: movl %eax,%ecx # byte count less prefix
++ shrl $2,%ecx # dword count
++ jz 4f # no dwords to move
++ cmpl $32,%ecx
++ jbe 2f # <= 32 dwords
++ # copy aligned dwords
++ rep; smovl
++ jmp 4f
++ # copy aligned dwords
++2: subl %esi,%edi
++ .p2align 4,,15
++3: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ addl $4,%esi
++ subl $1,%ecx
++ jnz 3b
++ addl %esi,%edi
++4: movl %eax,%ecx # byte count less prefix
++5: andl $3,%ecx # suffix byte count
++ jz 7f # no suffix
++ # copy suffix
++ xorl %eax,%eax
++6: movb (%esi,%eax,1),%dl
++ movb %dl,(%edi,%eax,1)
++ addl $1,%eax
++ subl $1,%ecx
++ jnz 6b
++7: popl %edi
++ popl %esi
++ ret
++ # copy from high to low
++cb_CopyLeft:
++ std
++ leal -4(%edi,%ecx),%edi # to + count - 4
++ movl %eax,%esi # from + count - 1
++ movl %ecx,%eax
++ subl $3,%esi # from + count - 4
++ cmpl $3,%ecx
++ jbe 5f # <= 3 bytes
++1: shrl $2,%ecx # dword count
++ jz 4f # no dwords to move
++ cmpl $32,%ecx
++ ja 3f # > 32 dwords
++ # copy dwords, aligned or not
++ subl %esi,%edi
++ .p2align 4,,15
++2: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ subl $4,%esi
++ subl $1,%ecx
++ jnz 2b
++ addl %esi,%edi
++ jmp 4f
++ # copy dwords, aligned or not
++3: rep; smovl
++4: movl %eax,%ecx # byte count
++5: andl $3,%ecx # suffix byte count
++ jz 7f # no suffix
++ # copy suffix
++ subl %esi,%edi
++ addl $3,%esi
++6: movb (%esi),%dl
++ movb %dl,(%edi,%esi,1)
++ subl $1,%esi
++ subl $1,%ecx
++ jnz 6b
++7: cld
++ popl %edi
++ popl %esi
++ ret
++
++ # Support for void Copy::arrayof_conjoint_bytes(void* from,
++ # void* to,
++ # size_t count)
++ #
++ # Same as _Copy_conjoint_bytes, except no source alignment check.
++ .p2align 4,,15
++ ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function)
++SYMBOL(_Copy_arrayof_conjoint_bytes):
++ pushl %esi
++ movl 4+12(%esp),%ecx # count
++ pushl %edi
++ movl 8+ 4(%esp),%esi # from
++ movl 8+ 8(%esp),%edi # to
++ cmpl %esi,%edi
++ leal -1(%esi,%ecx),%eax # from + count - 1
++ jbe acb_CopyRight
++ cmpl %eax,%edi
++ jbe acb_CopyLeft
++ # copy from low to high
++acb_CopyRight:
++ cmpl $3,%ecx
++ jbe 5f
++1: movl %ecx,%eax
++ shrl $2,%ecx
++ jz 4f
++ cmpl $32,%ecx
++ ja 3f
++ # copy aligned dwords
++ subl %esi,%edi
++ .p2align 4,,15
++2: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ addl $4,%esi
++ subl $1,%ecx
++ jnz 2b
++ addl %esi,%edi
++ jmp 4f
++ # copy aligned dwords
++3: rep; smovl
++4: movl %eax,%ecx
++5: andl $3,%ecx
++ jz 7f
++ # copy suffix
++ xorl %eax,%eax
++6: movb (%esi,%eax,1),%dl
++ movb %dl,(%edi,%eax,1)
++ addl $1,%eax
++ subl $1,%ecx
++ jnz 6b
++7: popl %edi
++ popl %esi
++ ret
++acb_CopyLeft:
++ std
++ leal -4(%edi,%ecx),%edi # to + count - 4
++ movl %eax,%esi # from + count - 1
++ movl %ecx,%eax
++ subl $3,%esi # from + count - 4
++ cmpl $3,%ecx
++ jbe 5f
++1: shrl $2,%ecx
++ jz 4f
++ cmpl $32,%ecx
++ jbe 2f # <= 32 dwords
++ rep; smovl
++ jmp 4f
++ .=.+8
++2: subl %esi,%edi
++ .p2align 4,,15
++3: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ subl $4,%esi
++ subl $1,%ecx
++ jnz 3b
++ addl %esi,%edi
++4: movl %eax,%ecx
++5: andl $3,%ecx
++ jz 7f
++ subl %esi,%edi
++ addl $3,%esi
++6: movb (%esi),%dl
++ movb %dl,(%edi,%esi,1)
++ subl $1,%esi
++ subl $1,%ecx
++ jnz 6b
++7: cld
++ popl %edi
++ popl %esi
++ ret
++
++ # Support for void Copy::conjoint_jshorts_atomic(void* from,
++ # void* to,
++ # size_t count)
++ .p2align 4,,15
++ ELF_TYPE(_Copy_conjoint_jshorts_atomic,@function)
++SYMBOL(_Copy_conjoint_jshorts_atomic):
++ pushl %esi
++ movl 4+12(%esp),%ecx # count
++ pushl %edi
++ movl 8+ 4(%esp),%esi # from
++ movl 8+ 8(%esp),%edi # to
++ cmpl %esi,%edi
++ leal -2(%esi,%ecx,2),%eax # from + count*2 - 2
++ jbe cs_CopyRight
++ cmpl %eax,%edi
++ jbe cs_CopyLeft
++ # copy from low to high
++cs_CopyRight:
++ # align source address at dword address boundary
++ movl %esi,%eax # original from
++ andl $3,%eax # either 0 or 2
++ jz 1f # no prefix
++ # copy prefix
++ subl $1,%ecx
++ jl 5f # zero count
++ movw (%esi),%dx
++ movw %dx,(%edi)
++ addl %eax,%esi # %eax == 2
++ addl %eax,%edi
++1: movl %ecx,%eax # word count less prefix
++ sarl %ecx # dword count
++ jz 4f # no dwords to move
++ cmpl $32,%ecx
++ jbe 2f # <= 32 dwords
++ # copy aligned dwords
++ rep; smovl
++ jmp 4f
++ # copy aligned dwords
++2: subl %esi,%edi
++ .p2align 4,,15
++3: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ addl $4,%esi
++ subl $1,%ecx
++ jnz 3b
++ addl %esi,%edi
++4: andl $1,%eax # suffix count
++ jz 5f # no suffix
++ # copy suffix
++ movw (%esi),%dx
++ movw %dx,(%edi)
++5: popl %edi
++ popl %esi
++ ret
++ # copy from high to low
++cs_CopyLeft:
++ std
++ leal -4(%edi,%ecx,2),%edi # to + count*2 - 4
++ movl %eax,%esi # from + count*2 - 2
++ movl %ecx,%eax
++ subl $2,%esi # from + count*2 - 4
++1: sarl %ecx # dword count
++ jz 4f # no dwords to move
++ cmpl $32,%ecx
++ ja 3f # > 32 dwords
++ subl %esi,%edi
++ .p2align 4,,15
++2: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ subl $4,%esi
++ subl $1,%ecx
++ jnz 2b
++ addl %esi,%edi
++ jmp 4f
++3: rep; smovl
++4: andl $1,%eax # suffix count
++ jz 5f # no suffix
++ # copy suffix
++ addl $2,%esi
++ addl $2,%edi
++ movw (%esi),%dx
++ movw %dx,(%edi)
++5: cld
++ popl %edi
++ popl %esi
++ ret
++
++ # Support for void Copy::arrayof_conjoint_jshorts(void* from,
++ # void* to,
++ # size_t count)
++ .p2align 4,,15
++ ELF_TYPE(_Copy_arrayof_conjoint_jshorts,@function)
++SYMBOL(_Copy_arrayof_conjoint_jshorts):
++ pushl %esi
++ movl 4+12(%esp),%ecx # count
++ pushl %edi
++ movl 8+ 4(%esp),%esi # from
++ movl 8+ 8(%esp),%edi # to
++ cmpl %esi,%edi
++ leal -2(%esi,%ecx,2),%eax # from + count*2 - 2
++ jbe acs_CopyRight
++ cmpl %eax,%edi
++ jbe acs_CopyLeft
++acs_CopyRight:
++ movl %ecx,%eax # word count
++ sarl %ecx # dword count
++ jz 4f # no dwords to move
++ cmpl $32,%ecx
++ jbe 2f # <= 32 dwords
++ # copy aligned dwords
++ rep; smovl
++ jmp 4f
++ # copy aligned dwords
++ .=.+5
++2: subl %esi,%edi
++ .p2align 4,,15
++3: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ addl $4,%esi
++ subl $1,%ecx
++ jnz 3b
++ addl %esi,%edi
++4: andl $1,%eax # suffix count
++ jz 5f # no suffix
++ # copy suffix
++ movw (%esi),%dx
++ movw %dx,(%edi)
++5: popl %edi
++ popl %esi
++ ret
++acs_CopyLeft:
++ std
++ leal -4(%edi,%ecx,2),%edi # to + count*2 - 4
++ movl %eax,%esi # from + count*2 - 2
++ movl %ecx,%eax
++ subl $2,%esi # from + count*2 - 4
++ sarl %ecx # dword count
++ jz 4f # no dwords to move
++ cmpl $32,%ecx
++ ja 3f # > 32 dwords
++ subl %esi,%edi
++ .p2align 4,,15
++2: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ subl $4,%esi
++ subl $1,%ecx
++ jnz 2b
++ addl %esi,%edi
++ jmp 4f
++3: rep; smovl
++4: andl $1,%eax # suffix count
++ jz 5f # no suffix
++ # copy suffix
++ addl $2,%esi
++ addl $2,%edi
++ movw (%esi),%dx
++ movw %dx,(%edi)
++5: cld
++ popl %edi
++ popl %esi
++ ret
++
++ # Support for void Copy::conjoint_jints_atomic(void* from,
++ # void* to,
++ # size_t count)
++ # Equivalent to
++ # arrayof_conjoint_jints
++ .p2align 4,,15
++ 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
++ movl 4+12(%esp),%ecx # count
++ pushl %edi
++ movl 8+ 4(%esp),%esi # from
++ movl 8+ 8(%esp),%edi # to
++ cmpl %esi,%edi
++ leal -4(%esi,%ecx,4),%eax # from + count*4 - 4
++ jbe ci_CopyRight
++ cmpl %eax,%edi
++ jbe ci_CopyLeft
++ci_CopyRight:
++ cmpl $32,%ecx
++ jbe 2f # <= 32 dwords
++ rep; smovl
++ popl %edi
++ popl %esi
++ ret
++ .=.+10
++2: subl %esi,%edi
++ jmp 4f
++ .p2align 4,,15
++3: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ addl $4,%esi
++4: subl $1,%ecx
++ jge 3b
++ popl %edi
++ popl %esi
++ ret
++ci_CopyLeft:
++ std
++ leal -4(%edi,%ecx,4),%edi # to + count*4 - 4
++ cmpl $32,%ecx
++ ja 4f # > 32 dwords
++ subl %eax,%edi # eax == from + count*4 - 4
++ jmp 3f
++ .p2align 4,,15
++2: movl (%eax),%edx
++ movl %edx,(%edi,%eax,1)
++ subl $4,%eax
++3: subl $1,%ecx
++ jge 2b
++ cld
++ popl %edi
++ popl %esi
++ ret
++4: movl %eax,%esi # from + count*4 - 4
++ rep; smovl
++ cld
++ popl %edi
++ popl %esi
++ ret
++
++ # Support for void Copy::conjoint_jlongs_atomic(jlong* from,
++ # jlong* to,
++ # size_t count)
++ #
++ # 32-bit
++ #
++ # count treated as signed
++ #
++ # // if (from > to) {
++ # while (--count >= 0) {
++ # *to++ = *from++;
++ # }
++ # } else {
++ # while (--count >= 0) {
++ # to[count] = from[count];
++ # }
++ # }
++ .p2align 4,,15
++ ELF_TYPE(_Copy_conjoint_jlongs_atomic,@function)
++SYMBOL(_Copy_conjoint_jlongs_atomic):
++ movl 4+8(%esp),%ecx # count
++ movl 4+0(%esp),%eax # from
++ movl 4+4(%esp),%edx # to
++ cmpl %eax,%edx
++ jae cla_CopyLeft
++cla_CopyRight:
++ subl %eax,%edx
++ jmp 2f
++ .p2align 4,,15
++1: fildll (%eax)
++ fistpll (%edx,%eax,1)
++ addl $8,%eax
++2: subl $1,%ecx
++ jge 1b
++ ret
++ .p2align 4,,15
++3: fildll (%eax,%ecx,8)
++ fistpll (%edx,%ecx,8)
++cla_CopyLeft:
++ subl $1,%ecx
++ jge 3b
++ ret
++
++ # Support for void Copy::arrayof_conjoint_jshorts(void* from,
++ # void* to,
++ # size_t count)
++ .p2align 4,,15
++ ELF_TYPE(_mmx_Copy_arrayof_conjoint_jshorts,@function)
++SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts):
++ pushl %esi
++ movl 4+12(%esp),%ecx
++ pushl %edi
++ movl 8+ 4(%esp),%esi
++ movl 8+ 8(%esp),%edi
++ cmpl %esi,%edi
++ leal -2(%esi,%ecx,2),%eax
++ jbe mmx_acs_CopyRight
++ cmpl %eax,%edi
++ jbe mmx_acs_CopyLeft
++mmx_acs_CopyRight:
++ movl %ecx,%eax
++ sarl %ecx
++ je 5f
++ cmpl $33,%ecx
++ jae 3f
++1: subl %esi,%edi
++ .p2align 4,,15
++2: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ addl $4,%esi
++ subl $1,%ecx
++ jnz 2b
++ addl %esi,%edi
++ jmp 5f
++3: smovl # align to 8 bytes, we know we are 4 byte aligned to start
++ subl $1,%ecx
++4: .p2align 4,,15
++ movq 0(%esi),%mm0
++ addl $64,%edi
++ movq 8(%esi),%mm1
++ subl $16,%ecx
++ movq 16(%esi),%mm2
++ movq %mm0,-64(%edi)
++ movq 24(%esi),%mm0
++ movq %mm1,-56(%edi)
++ movq 32(%esi),%mm1
++ movq %mm2,-48(%edi)
++ movq 40(%esi),%mm2
++ movq %mm0,-40(%edi)
++ movq 48(%esi),%mm0
++ movq %mm1,-32(%edi)
++ movq 56(%esi),%mm1
++ movq %mm2,-24(%edi)
++ movq %mm0,-16(%edi)
++ addl $64,%esi
++ movq %mm1,-8(%edi)
++ cmpl $16,%ecx
++ jge 4b
++ emms
++ testl %ecx,%ecx
++ ja 1b
++5: andl $1,%eax
++ je 7f
++6: movw (%esi),%dx
++ movw %dx,(%edi)
++7: popl %edi
++ popl %esi
++ ret
++mmx_acs_CopyLeft:
++ std
++ leal -4(%edi,%ecx,2),%edi
++ movl %eax,%esi
++ movl %ecx,%eax
++ subl $2,%esi
++ sarl %ecx
++ je 4f
++ cmpl $32,%ecx
++ ja 3f
++ subl %esi,%edi
++ .p2align 4,,15
++2: movl (%esi),%edx
++ movl %edx,(%edi,%esi,1)
++ subl $4,%esi
++ subl $1,%ecx
++ jnz 2b
++ addl %esi,%edi
++ jmp 4f
++3: rep; smovl
++4: andl $1,%eax
++ je 6f
++ addl $2,%esi
++ addl $2,%edi
++5: movw (%esi),%dx
++ movw %dx,(%edi)
++6: cld
++ popl %edi
++ popl %esi
++ ret
++
++
++ # Support for jlong Atomic::cmpxchg(jlong exchange_value,
++ # volatile jlong* dest,
++ # jlong compare_value,
++ # bool is_MP)
++ #
++ .p2align 4,,15
++ ELF_TYPE(_Atomic_cmpxchg_long,@function)
++SYMBOL(_Atomic_cmpxchg_long):
++ # 8(%esp) : return PC
++ pushl %ebx # 4(%esp) : old %ebx
++ pushl %edi # 0(%esp) : old %edi
++ movl 12(%esp), %ebx # 12(%esp) : exchange_value (low)
++ movl 16(%esp), %ecx # 16(%esp) : exchange_value (high)
++ movl 24(%esp), %eax # 24(%esp) : compare_value (low)
++ movl 28(%esp), %edx # 28(%esp) : compare_value (high)
++ movl 20(%esp), %edi # 20(%esp) : dest
++ cmpl $0, 32(%esp) # 32(%esp) : is_MP
++ je 1f
++ lock
++1: cmpxchg8b (%edi)
++ popl %edi
++ popl %ebx
++ ret
++
++
++ # 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)
++SYMBOL(_Atomic_move_long):
++ movl 4(%esp), %eax # src
++ fildll (%eax)
++ movl 8(%esp), %eax # dest
++ fistpll (%eax)
++ ret
++
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,173 @@
++//
++// Copyright (c) 2003, 2006, 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.
++//
++//
++
++// AMD64 Bsd Architecture Description File
++
++//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
++// This block specifies the encoding classes used by the compiler to
++// output byte streams. Encoding classes generate functions which are
++// called by Machine Instruction Nodes in order to generate the bit
++// encoding of the instruction. Operands specify their base encoding
++// interface with the interface keyword. There are currently
++// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
++// COND_INTER. REG_INTER causes an operand to generate a function
++// which returns its register number when queried. CONST_INTER causes
++// an operand to generate a function which returns the value of the
++// constant when queried. MEMORY_INTER causes an operand to generate
++// four functions which return the Base Register, the Index Register,
++// the Scale Value, and the Offset Value of the operand when queried.
++// COND_INTER causes an operand to generate six functions which return
++// the encoding code (ie - encoding bits for the instruction)
++// associated with each basic boolean condition for a conditional
++// instruction. Instructions specify two basic values for encoding.
++// They use the ins_encode keyword to specify their encoding class
++// (which must be one of the class names specified in the encoding
++// block), and they use the opcode keyword to specify, in order, their
++// primary, secondary, and tertiary opcode. Only the opcode sections
++// which a particular instruction needs for encoding need to be
++// specified.
++encode %{
++ // Build emit functions for each basic byte or larger field in the intel
++ // encoding scheme (opcode, rm, sib, immediate), and call them from C++
++ // code in the enc_class source block. Emit functions will live in the
++ // main source block for now. In future, we can generalize this by
++ // adding a syntax that specifies the sizes of fields in an order,
++ // so that the adlc can build the emit functions automagically
++
++ enc_class Java_To_Runtime(method meth)
++ %{
++ // No relocation needed
++
++ // movq r10, <meth>
++ emit_opcode(cbuf, Assembler::REX_WB);
++ emit_opcode(cbuf, 0xB8 | (R10_enc - 8));
++ emit_d64(cbuf, (int64_t) $meth$$method);
++
++ // call (r10)
++ emit_opcode(cbuf, Assembler::REX_B);
++ emit_opcode(cbuf, 0xFF);
++ emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
++ %}
++
++ enc_class bsd_breakpoint
++ %{
++ MacroAssembler* masm = new MacroAssembler(&cbuf);
++ masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
++ %}
++
++ enc_class call_epilog
++ %{
++ if (VerifyStackAtCalls) {
++ // Check that stack depth is unchanged: find majik cookie on stack
++ int framesize =
++ ra_->reg2offset_unchecked(OptoReg::add(ra_->_matcher._old_SP, -3*VMRegImpl::slots_per_word));
++ if (framesize) {
++ if (framesize < 0x80) {
++ emit_opcode(cbuf, Assembler::REX_W);
++ emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
++ emit_d8(cbuf, 0x7C);
++ emit_d8(cbuf, 0x24);
++ emit_d8(cbuf, framesize); // Find majik cookie from ESP
++ emit_d32(cbuf, 0xbadb100d);
++ } else {
++ emit_opcode(cbuf, Assembler::REX_W);
++ emit_opcode(cbuf, 0x81); // cmpq [rsp+0],0xbadb1ood
++ emit_d8(cbuf, 0xBC);
++ emit_d8(cbuf, 0x24);
++ emit_d32(cbuf, framesize); // Find majik cookie from ESP
++ emit_d32(cbuf, 0xbadb100d);
++ }
++ }
++ // jmp EQ around INT3
++ // QQQ TODO
++ const int jump_around = 5; // size of call to breakpoint, 1 for CC
++ emit_opcode(cbuf, 0x74);
++ emit_d8(cbuf, jump_around);
++ // QQQ temporary
++ emit_break(cbuf);
++ // Die if stack mismatch
++ // emit_opcode(cbuf,0xCC);
++ }
++ %}
++
++%}
++
++// INSTRUCTIONS -- Platform dependent
++
++//----------OS and Locking Instructions----------------------------------------
++
++// This name is KNOWN by the ADLC and cannot be changed.
++// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
++// for this guy.
++instruct tlsLoadP(r15_RegP dst)
++%{
++ match(Set dst (ThreadLocal));
++ effect(DEF dst);
++
++ size(0);
++ format %{ "# TLS is in R15" %}
++ ins_encode( /*empty encoding*/ );
++ ins_pipe(ialu_reg_reg);
++%}
++
++// Die now
++instruct ShouldNotReachHere()
++%{
++ match(Halt);
++
++ // Use the following format syntax
++ format %{ "int3\t# ShouldNotReachHere" %}
++ // QQQ TODO for now call breakpoint
++ // opcode(0xCC);
++ // ins_encode(Opc);
++ ins_encode(bsd_breakpoint);
++ ins_pipe(pipe_slow);
++%}
++
++
++// Platform dependent source
++
++source
++%{
++
++int MachCallRuntimeNode::ret_addr_offset() {
++ return 13; // movq r10,#addr; callq (r10)
++}
++
++// emit an interrupt that is caught by the debugger
++void emit_break(CodeBuffer& cbuf) {
++ // Debugger doesn't really catch this but best we can do so far QQQ
++ MacroAssembler* masm = new MacroAssembler(&cbuf);
++ masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
++}
++
++void MachBreakpointNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
++ emit_break(cbuf);
++}
++
++uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
++ return 5;
++}
++
++%}
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,410 @@
++#
++# Copyright (c) 2004, 2007, 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.
++#
++
++#ifdef __APPLE__
++# Darwin uses _ prefixed global symbols
++#define SYMBOL(s) _ ## s
++#define ELF_TYPE(name, description)
++#else
++#define SYMBOL(s) s
++#define ELF_TYPE(name, description) .type name,description
++#endif
++
++ # 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.
++
++ .globl SYMBOL(_Copy_arrayof_conjoint_bytes)
++ .globl SYMBOL(_Copy_arrayof_conjoint_jshorts)
++ .globl SYMBOL(_Copy_conjoint_jshorts_atomic)
++ .globl SYMBOL(_Copy_arrayof_conjoint_jints)
++ .globl SYMBOL(_Copy_conjoint_jints_atomic)
++ .globl SYMBOL(_Copy_arrayof_conjoint_jlongs)
++ .globl SYMBOL(_Copy_conjoint_jlongs_atomic)
++
++ .text
++
++ .globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
++ .p2align 4,,15
++ ELF_TYPE(SafeFetch32,@function)
++ // Prototype: int SafeFetch32 (int * Adr, int ErrValue)
++SYMBOL(SafeFetch32):
++ movl %esi, %eax
++SYMBOL(Fetch32PFI):
++ movl (%rdi), %eax
++SYMBOL(Fetch32Resume):
++ ret
++
++ .globl SYMBOL(SafeFetchN), SYMBOL(FetchNPFI), SYMBOL(FetchNResume)
++ .p2align 4,,15
++ ELF_TYPE(SafeFetchN,@function)
++ // Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue)
++SYMBOL(SafeFetchN):
++ movq %rsi, %rax
++SYMBOL(FetchNPFI):
++ movq (%rdi), %rax
++SYMBOL(FetchNResume):
++ ret
++
++ .globl SYMBOL(SpinPause)
++ .p2align 4,,15
++ ELF_TYPE(SpinPause,@function)
++SYMBOL(SpinPause):
++ rep
++ nop
++ movq $1, %rax
++ ret
++
++ # Support for void Copy::arrayof_conjoint_bytes(void* from,
++ # void* to,
++ # size_t count)
++ # rdi - from
++ # rsi - to
++ # rdx - count, treated as ssize_t
++ #
++ .p2align 4,,15
++ ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function)
++SYMBOL(_Copy_arrayof_conjoint_bytes):
++ movq %rdx,%r8 # byte count
++ shrq $3,%rdx # qword count
++ cmpq %rdi,%rsi
++ leaq -1(%rdi,%r8,1),%rax # from + bcount*1 - 1
++ jbe acb_CopyRight
++ cmpq %rax,%rsi
++ jbe acb_CopyLeft
++acb_CopyRight:
++ leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8
++ leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8
++ negq %rdx
++ jmp 7f
++ .p2align 4,,15
++1: movq 8(%rax,%rdx,8),%rsi
++ movq %rsi,8(%rcx,%rdx,8)
++ addq $1,%rdx
++ jnz 1b
++2: testq $4,%r8 # check for trailing dword
++ jz 3f
++ movl 8(%rax),%esi # copy trailing dword
++ movl %esi,8(%rcx)
++ addq $4,%rax
++ addq $4,%rcx # original %rsi is trashed, so we
++ # can't use it as a base register
++3: testq $2,%r8 # check for trailing word
++ jz 4f
++ movw 8(%rax),%si # copy trailing word
++ movw %si,8(%rcx)
++ addq $2,%rcx
++4: testq $1,%r8 # check for trailing byte
++ jz 5f
++ movb -1(%rdi,%r8,1),%al # copy trailing byte
++ movb %al,8(%rcx)
++5: ret
++ .p2align 4,,15
++6: movq -24(%rax,%rdx,8),%rsi
++ movq %rsi,-24(%rcx,%rdx,8)
++ movq -16(%rax,%rdx,8),%rsi
++ movq %rsi,-16(%rcx,%rdx,8)
++ movq -8(%rax,%rdx,8),%rsi
++ movq %rsi,-8(%rcx,%rdx,8)
++ movq (%rax,%rdx,8),%rsi
++ movq %rsi,(%rcx,%rdx,8)
++7: addq $4,%rdx
++ jle 6b
++ subq $4,%rdx
++ jl 1b
++ jmp 2b
++acb_CopyLeft:
++ testq $1,%r8 # check for trailing byte
++ jz 1f
++ movb -1(%rdi,%r8,1),%cl # copy trailing byte
++ movb %cl,-1(%rsi,%r8,1)
++ subq $1,%r8 # adjust for possible trailing word
++1: testq $2,%r8 # check for trailing word
++ jz 2f
++ movw -2(%rdi,%r8,1),%cx # copy trailing word
++ movw %cx,-2(%rsi,%r8,1)
++2: testq $4,%r8 # check for trailing dword
++ jz 5f
++ movl (%rdi,%rdx,8),%ecx # copy trailing dword
++ movl %ecx,(%rsi,%rdx,8)
++ jmp 5f
++ .p2align 4,,15
++3: movq -8(%rdi,%rdx,8),%rcx
++ movq %rcx,-8(%rsi,%rdx,8)
++ subq $1,%rdx
++ jnz 3b
++ ret
++ .p2align 4,,15
++4: movq 24(%rdi,%rdx,8),%rcx
++ movq %rcx,24(%rsi,%rdx,8)
++ movq 16(%rdi,%rdx,8),%rcx
++ movq %rcx,16(%rsi,%rdx,8)
++ movq 8(%rdi,%rdx,8),%rcx
++ movq %rcx,8(%rsi,%rdx,8)
++ movq (%rdi,%rdx,8),%rcx
++ movq %rcx,(%rsi,%rdx,8)
++5: subq $4,%rdx
++ jge 4b
++ addq $4,%rdx
++ jg 3b
++ ret
++
++ # Support for void Copy::arrayof_conjoint_jshorts(void* from,
++ # void* to,
++ # size_t count)
++ # Equivalent to
++ # conjoint_jshorts_atomic
++ #
++ # If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
++ # let the hardware handle it. The tow or four words within dwords
++ # or qwords that span cache line boundaries will still be loaded
++ # and stored atomically.
++ #
++ # rdi - from
++ # rsi - to
++ # rdx - count, treated as ssize_t
++ #
++ .p2align 4,,15
++ ELF_TYPE(_Copy_arrayof_conjoint_jshorts,@function)
++ ELF_TYPE(_Copy_conjoint_jshorts_atomic,@function)
++SYMBOL(_Copy_arrayof_conjoint_jshorts):
++SYMBOL(_Copy_conjoint_jshorts_atomic):
++ movq %rdx,%r8 # word count
++ shrq $2,%rdx # qword count
++ cmpq %rdi,%rsi
++ leaq -2(%rdi,%r8,2),%rax # from + wcount*2 - 2
++ jbe acs_CopyRight
++ cmpq %rax,%rsi
++ jbe acs_CopyLeft
++acs_CopyRight:
++ leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8
++ leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8
++ negq %rdx
++ jmp 6f
++1: movq 8(%rax,%rdx,8),%rsi
++ movq %rsi,8(%rcx,%rdx,8)
++ addq $1,%rdx
++ jnz 1b
++2: testq $2,%r8 # check for trailing dword
++ jz 3f
++ movl 8(%rax),%esi # copy trailing dword
++ movl %esi,8(%rcx)
++ addq $4,%rcx # original %rsi is trashed, so we
++ # can't use it as a base register
++3: testq $1,%r8 # check for trailing word
++ jz 4f
++ movw -2(%rdi,%r8,2),%si # copy trailing word
++ movw %si,8(%rcx)
++4: ret
++ .p2align 4,,15
++5: movq -24(%rax,%rdx,8),%rsi
++ movq %rsi,-24(%rcx,%rdx,8)
++ movq -16(%rax,%rdx,8),%rsi
++ movq %rsi,-16(%rcx,%rdx,8)
++ movq -8(%rax,%rdx,8),%rsi
++ movq %rsi,-8(%rcx,%rdx,8)
++ movq (%rax,%rdx,8),%rsi
++ movq %rsi,(%rcx,%rdx,8)
++6: addq $4,%rdx
++ jle 5b
++ subq $4,%rdx
++ jl 1b
++ jmp 2b
++acs_CopyLeft:
++ testq $1,%r8 # check for trailing word
++ jz 1f
++ movw -2(%rdi,%r8,2),%cx # copy trailing word
++ movw %cx,-2(%rsi,%r8,2)
++1: testq $2,%r8 # check for trailing dword
++ jz 4f
++ movl (%rdi,%rdx,8),%ecx # copy trailing dword
++ movl %ecx,(%rsi,%rdx,8)
++ jmp 4f
++2: movq -8(%rdi,%rdx,8),%rcx
++ movq %rcx,-8(%rsi,%rdx,8)
++ subq $1,%rdx
++ jnz 2b
++ ret
++ .p2align 4,,15
++3: movq 24(%rdi,%rdx,8),%rcx
++ movq %rcx,24(%rsi,%rdx,8)
++ movq 16(%rdi,%rdx,8),%rcx
++ movq %rcx,16(%rsi,%rdx,8)
++ movq 8(%rdi,%rdx,8),%rcx
++ movq %rcx,8(%rsi,%rdx,8)
++ movq (%rdi,%rdx,8),%rcx
++ movq %rcx,(%rsi,%rdx,8)
++4: subq $4,%rdx
++ jge 3b
++ addq $4,%rdx
++ jg 2b
++ ret
++
++ # Support for void Copy::arrayof_conjoint_jints(jint* from,
++ # jint* to,
++ # size_t count)
++ # Equivalent to
++ # conjoint_jints_atomic
++ #
++ # If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
++ # the hardware handle it. The two dwords within qwords that span
++ # cache line boundaries will still be loaded and stored atomically.
++ #
++ # rdi - from
++ # rsi - to
++ # rdx - count, treated as ssize_t
++ #
++ .p2align 4,,15
++ ELF_TYPE(_Copy_arrayof_conjoint_jints,@function)
++ ELF_TYPE(_Copy_conjoint_jints_atomic,@function)
++SYMBOL(_Copy_arrayof_conjoint_jints):
++SYMBOL(_Copy_conjoint_jints_atomic):
++ movq %rdx,%r8 # dword count
++ shrq %rdx # qword count
++ cmpq %rdi,%rsi
++ leaq -4(%rdi,%r8,4),%rax # from + dcount*4 - 4
++ jbe aci_CopyRight
++ cmpq %rax,%rsi
++ jbe aci_CopyLeft
++aci_CopyRight:
++ leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8
++ leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8
++ negq %rdx
++ jmp 5f
++ .p2align 4,,15
++1: movq 8(%rax,%rdx,8),%rsi
++ movq %rsi,8(%rcx,%rdx,8)
++ addq $1,%rdx
++ jnz 1b
++2: testq $1,%r8 # check for trailing dword
++ jz 3f
++ movl 8(%rax),%esi # copy trailing dword
++ movl %esi,8(%rcx)
++3: ret
++ .p2align 4,,15
++4: movq -24(%rax,%rdx,8),%rsi
++ movq %rsi,-24(%rcx,%rdx,8)
++ movq -16(%rax,%rdx,8),%rsi
++ movq %rsi,-16(%rcx,%rdx,8)
++ movq -8(%rax,%rdx,8),%rsi
++ movq %rsi,-8(%rcx,%rdx,8)
++ movq (%rax,%rdx,8),%rsi
++ movq %rsi,(%rcx,%rdx,8)
++5: addq $4,%rdx
++ jle 4b
++ subq $4,%rdx
++ jl 1b
++ jmp 2b
++aci_CopyLeft:
++ testq $1,%r8 # check for trailing dword
++ jz 3f
++ movl -4(%rdi,%r8,4),%ecx # copy trailing dword
++ movl %ecx,-4(%rsi,%r8,4)
++ jmp 3f
++1: movq -8(%rdi,%rdx,8),%rcx
++ movq %rcx,-8(%rsi,%rdx,8)
++ subq $1,%rdx
++ jnz 1b
++ ret
++ .p2align 4,,15
++2: movq 24(%rdi,%rdx,8),%rcx
++ movq %rcx,24(%rsi,%rdx,8)
++ movq 16(%rdi,%rdx,8),%rcx
++ movq %rcx,16(%rsi,%rdx,8)
++ movq 8(%rdi,%rdx,8),%rcx
++ movq %rcx,8(%rsi,%rdx,8)
++ movq (%rdi,%rdx,8),%rcx
++ movq %rcx,(%rsi,%rdx,8)
++3: subq $4,%rdx
++ jge 2b
++ addq $4,%rdx
++ jg 1b
++ ret
++
++ # Support for void Copy::arrayof_conjoint_jlongs(jlong* from,
++ # jlong* to,
++ # size_t count)
++ # Equivalent to
++ # conjoint_jlongs_atomic
++ # arrayof_conjoint_oops
++ # conjoint_oops_atomic
++ #
++ # rdi - from
++ # rsi - to
++ # rdx - count, treated as ssize_t
++ #
++ .p2align 4,,15
++ ELF_TYPE(_Copy_arrayof_conjoint_jlongs,@function)
++ ELF_TYPE(_Copy_conjoint_jlongs_atomic,@function)
++SYMBOL(_Copy_arrayof_conjoint_jlongs):
++SYMBOL(_Copy_conjoint_jlongs_atomic):
++ cmpq %rdi,%rsi
++ leaq -8(%rdi,%rdx,8),%rax # from + count*8 - 8
++ jbe acl_CopyRight
++ cmpq %rax,%rsi
++ jbe acl_CopyLeft
++acl_CopyRight:
++ leaq -8(%rsi,%rdx,8),%rcx # to + count*8 - 8
++ negq %rdx
++ jmp 3f
++1: movq 8(%rax,%rdx,8),%rsi
++ movq %rsi,8(%rcx,%rdx,8)
++ addq $1,%rdx
++ jnz 1b
++ ret
++ .p2align 4,,15
++2: movq -24(%rax,%rdx,8),%rsi
++ movq %rsi,-24(%rcx,%rdx,8)
++ movq -16(%rax,%rdx,8),%rsi
++ movq %rsi,-16(%rcx,%rdx,8)
++ movq -8(%rax,%rdx,8),%rsi
++ movq %rsi,-8(%rcx,%rdx,8)
++ movq (%rax,%rdx,8),%rsi
++ movq %rsi,(%rcx,%rdx,8)
++3: addq $4,%rdx
++ jle 2b
++ subq $4,%rdx
++ jl 1b
++ ret
++4: movq -8(%rdi,%rdx,8),%rcx
++ movq %rcx,-8(%rsi,%rdx,8)
++ subq $1,%rdx
++ jnz 4b
++ ret
++ .p2align 4,,15
++5: movq 24(%rdi,%rdx,8),%rcx
++ movq %rcx,24(%rsi,%rdx,8)
++ movq 16(%rdi,%rdx,8),%rcx
++ movq %rcx,16(%rsi,%rdx,8)
++ movq 8(%rdi,%rdx,8),%rcx
++ movq %rcx,8(%rsi,%rdx,8)
++ movq (%rdi,%rdx,8),%rcx
++ movq %rcx,(%rsi,%rdx,8)
++acl_CopyLeft:
++ subq $4,%rdx
++ jge 5b
++ addq $4,%rdx
++ jg 4b
++ ret
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (c) 1999, 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_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
++#define OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
++
++#ifndef _ALLBSD_SOURCE
++#include <byteswap.h>
++#endif
++
++#ifdef __APPLE__
++#include <libkern/OSByteOrder.h>
++#endif
++
++#if defined(AMD64)
++# if defined(__APPLE__)
++# define bswap_16(x) OSSwapInt16(x)
++# define bswap_32(x) OSSwapInt32(x)
++# define bswap_64(x) OSSwapInt64(x)
++# elif defined(__OpenBSD__)
++# define bswap_16(x) swap16(x)
++# define bswap_32(x) swap32(x)
++# define bswap_64(x) swap64(x)
++# elif defined(__NetBSD__)
++# define bswap_16(x) bswap16(x)
++# define bswap_32(x) bswap32(x)
++# define bswap_64(x) bswap64(x)
++# else
++# define bswap_16(x) __bswap16(x)
++# define bswap_32(x) __bswap32(x)
++# define bswap_64(x) __bswap64(x)
++# endif
++#endif
++
++// Efficient swapping of data bytes from Java byte
++// ordering to native byte ordering and vice versa.
++inline u2 Bytes::swap_u2(u2 x) {
++#ifdef AMD64
++ return bswap_16(x);
++#else
++ u2 ret;
++ __asm__ __volatile__ (
++ "movw %0, %%ax;"
++ "xchg %%al, %%ah;"
++ "movw %%ax, %0"
++ :"=r" (ret) // output : register 0 => ret
++ :"0" (x) // input : x => register 0
++ :"ax", "0" // clobbered registers
++ );
++ return ret;
++#endif // AMD64
++}
++
++inline u4 Bytes::swap_u4(u4 x) {
++#ifdef AMD64
++ return bswap_32(x);
++#else
++ u4 ret;
++ __asm__ __volatile__ (
++ "bswap %0"
++ :"=r" (ret) // output : register 0 => ret
++ :"0" (x) // input : x => register 0
++ :"0" // clobbered register
++ );
++ return ret;
++#endif // AMD64
++}
++
++#ifdef AMD64
++inline u8 Bytes::swap_u8(u8 x) {
++#ifdef SPARC_WORKS
++ // workaround for SunStudio12 CR6615391
++ __asm__ __volatile__ (
++ "bswapq %0"
++ :"=r" (x) // output : register 0 => x
++ :"0" (x) // input : x => register 0
++ :"0" // clobbered register
++ );
++ return x;
++#else
++ return bswap_64(x);
++#endif
++}
++#else
++// Helper function for swap_u8
++inline u8 Bytes::swap_u8_base(u4 x, u4 y) {
++ return (((u8)swap_u4(x))<<32) | swap_u4(y);
++}
++
++inline u8 Bytes::swap_u8(u8 x) {
++ return swap_u8_base(*(u4*)&x, *(((u4*)&x)+1));
++}
++#endif // !AMD64
++
++#endif // OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/copy_bsd_x86.inline.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/copy_bsd_x86.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/copy_bsd_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/copy_bsd_x86.inline.hpp 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,309 @@
++/*
++ * 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_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
++#define OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
++
++static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++#ifdef AMD64
++ (void)memmove(to, from, count * HeapWordSize);
++#else
++ // Includes a zero-count check.
++ intx temp;
++ __asm__ volatile(" testl %6,%6 ;"
++ " jz 7f ;"
++ " cmpl %4,%5 ;"
++ " leal -4(%4,%6,4),%3;"
++ " jbe 1f ;"
++ " cmpl %7,%5 ;"
++ " jbe 4f ;"
++ "1: cmpl $32,%6 ;"
++ " ja 3f ;"
++ " subl %4,%1 ;"
++ "2: movl (%4),%3 ;"
++ " movl %7,(%5,%4,1) ;"
++ " addl $4,%0 ;"
++ " subl $1,%2 ;"
++ " jnz 2b ;"
++ " jmp 7f ;"
++ "3: rep; smovl ;"
++ " jmp 7f ;"
++ "4: cmpl $32,%2 ;"
++ " movl %7,%0 ;"
++ " leal -4(%5,%6,4),%1;"
++ " ja 6f ;"
++ " subl %4,%1 ;"
++ "5: movl (%4),%3 ;"
++ " movl %7,(%5,%4,1) ;"
++ " subl $4,%0 ;"
++ " subl $1,%2 ;"
++ " jnz 5b ;"
++ " jmp 7f ;"
++ "6: std ;"
++ " rep; smovl ;"
++ " cld ;"
++ "7: nop "
++ : "=S" (from), "=D" (to), "=c" (count), "=r" (temp)
++ : "0" (from), "1" (to), "2" (count), "3" (temp)
++ : "memory", "flags");
++#endif // AMD64
++}
++
++static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++#ifdef AMD64
++ switch (count) {
++ case 8: to[7] = from[7];
++ case 7: to[6] = from[6];
++ case 6: to[5] = from[5];
++ case 5: to[4] = from[4];
++ case 4: to[3] = from[3];
++ case 3: to[2] = from[2];
++ case 2: to[1] = from[1];
++ case 1: to[0] = from[0];
++ case 0: break;
++ default:
++ (void)memcpy(to, from, count * HeapWordSize);
++ break;
++ }
++#else
++ // Includes a zero-count check.
++ intx temp;
++ __asm__ volatile(" testl %6,%6 ;"
++ " jz 3f ;"
++ " cmpl $32,%6 ;"
++ " ja 2f ;"
++ " subl %4,%1 ;"
++ "1: movl (%4),%3 ;"
++ " movl %7,(%5,%4,1);"
++ " addl $4,%0 ;"
++ " subl $1,%2 ;"
++ " jnz 1b ;"
++ " jmp 3f ;"
++ "2: rep; smovl ;"
++ "3: nop "
++ : "=S" (from), "=D" (to), "=c" (count), "=r" (temp)
++ : "0" (from), "1" (to), "2" (count), "3" (temp)
++ : "memory", "cc");
++#endif // AMD64
++}
++
++static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
++#ifdef AMD64
++ switch (count) {
++ case 8: to[7] = from[7];
++ case 7: to[6] = from[6];
++ case 6: to[5] = from[5];
++ case 5: to[4] = from[4];
++ case 4: to[3] = from[3];
++ case 3: to[2] = from[2];
++ case 2: to[1] = from[1];
++ case 1: to[0] = from[0];
++ case 0: break;
++ default:
++ while (count-- > 0) {
++ *to++ = *from++;
++ }
++ break;
++ }
++#else
++ // pd_disjoint_words is word-atomic in this implementation.
++ pd_disjoint_words(from, to, count);
++#endif // AMD64
++}
++
++static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++ pd_conjoint_words(from, to, count);
++}
++
++static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++ pd_disjoint_words(from, to, count);
++}
++
++static void pd_conjoint_bytes(void* from, void* to, size_t count) {
++#ifdef AMD64
++ (void)memmove(to, from, count);
++#else
++ // Includes a zero-count check.
++ intx temp;
++ __asm__ volatile(" testl %6,%6 ;"
++ " jz 13f ;"
++ " cmpl %4,%5 ;"
++ " leal -1(%4,%6),%3 ;"
++ " jbe 1f ;"
++ " cmpl %7,%5 ;"
++ " jbe 8f ;"
++ "1: cmpl $3,%6 ;"
++ " jbe 6f ;"
++ " movl %6,%3 ;"
++ " movl $4,%2 ;"
++ " subl %4,%2 ;"
++ " andl $3,%2 ;"
++ " jz 2f ;"
++ " subl %6,%3 ;"
++ " rep; smovb ;"
++ "2: movl %7,%2 ;"
++ " shrl $2,%2 ;"
++ " jz 5f ;"
++ " cmpl $32,%2 ;"
++ " ja 4f ;"
++ " subl %4,%1 ;"
++ "3: movl (%4),%%edx ;"
++ " movl %%edx,(%5,%4,1);"
++ " addl $4,%0 ;"
++ " subl $1,%2 ;"
++ " jnz 3b ;"
++ " addl %4,%1 ;"
++ " jmp 5f ;"
++ "4: rep; smovl ;"
++ "5: movl %7,%2 ;"
++ " andl $3,%2 ;"
++ " jz 13f ;"
++ "6: xorl %7,%3 ;"
++ "7: movb (%4,%7,1),%%dl ;"
++ " movb %%dl,(%5,%7,1) ;"
++ " addl $1,%3 ;"
++ " subl $1,%2 ;"
++ " jnz 7b ;"
++ " jmp 13f ;"
++ "8: std ;"
++ " cmpl $12,%2 ;"
++ " ja 9f ;"
++ " movl %7,%0 ;"
++ " leal -1(%6,%5),%1 ;"
++ " jmp 11f ;"
++ "9: xchgl %3,%2 ;"
++ " movl %6,%0 ;"
++ " addl $1,%2 ;"
++ " leal -1(%7,%5),%1 ;"
++ " andl $3,%2 ;"
++ " jz 10f ;"
++ " subl %6,%3 ;"
++ " rep; smovb ;"
++ "10: movl %7,%2 ;"
++ " subl $3,%0 ;"
++ " shrl $2,%2 ;"
++ " subl $3,%1 ;"
++ " rep; smovl ;"
++ " andl $3,%3 ;"
++ " jz 12f ;"
++ " movl %7,%2 ;"
++ " addl $3,%0 ;"
++ " addl $3,%1 ;"
++ "11: rep; smovb ;"
++ "12: cld ;"
++ "13: nop ;"
++ : "=S" (from), "=D" (to), "=c" (count), "=r" (temp)
++ : "0" (from), "1" (to), "2" (count), "3" (temp)
++ : "memory", "flags", "%edx");
++#endif // AMD64
++}
++
++static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
++ pd_conjoint_bytes(from, to, count);
++}
++
++static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
++ _Copy_conjoint_jshorts_atomic(from, to, count);
++}
++
++static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
++#ifdef AMD64
++ _Copy_conjoint_jints_atomic(from, to, count);
++#else
++ assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size");
++ // pd_conjoint_words is word-atomic in this implementation.
++ pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
++#endif // AMD64
++}
++
++static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
++#ifdef AMD64
++ _Copy_conjoint_jlongs_atomic(from, to, count);
++#else
++ // Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't.
++ if (from > to) {
++ while (count-- > 0) {
++ __asm__ volatile("fildll (%0); fistpll (%1)"
++ :
++ : "r" (from), "r" (to)
++ : "memory" );
++ ++from;
++ ++to;
++ }
++ } else {
++ while (count-- > 0) {
++ __asm__ volatile("fildll (%0,%2,8); fistpll (%1,%2,8)"
++ :
++ : "r" (from), "r" (to), "r" (count)
++ : "memory" );
++ }
++ }
++#endif // AMD64
++}
++
++static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
++#ifdef AMD64
++ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
++ _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
++#else
++ assert(HeapWordSize == BytesPerOop, "heapwords and oops must be the same size");
++ // pd_conjoint_words is word-atomic in this implementation.
++ pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
++#endif // AMD64
++}
++
++static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
++ _Copy_arrayof_conjoint_bytes(from, to, count);
++}
++
++static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
++ _Copy_arrayof_conjoint_jshorts(from, to, count);
++}
++
++static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
++#ifdef AMD64
++ _Copy_arrayof_conjoint_jints(from, to, count);
++#else
++ pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
++#endif // AMD64
++}
++
++static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
++#ifdef AMD64
++ _Copy_arrayof_conjoint_jlongs(from, to, count);
++#else
++ pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
++#endif // AMD64
++}
++
++static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
++#ifdef AMD64
++ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
++ _Copy_arrayof_conjoint_jlongs(from, to, count);
++#else
++ pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
++#endif // AMD64
++}
++
++#endif // OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2000, 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_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
++#define OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
++
++//
++// Sets the default values for platform dependent flags used by the runtime system.
++// (see globals.hpp)
++//
++define_pd_global(bool, DontYieldALot, false);
++#ifdef AMD64
++define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
++define_pd_global(intx, VMThreadStackSize, 1024);
++#else
++// ThreadStackSize 320 allows a couple of test cases to run while
++// keeping the number of threads that can be created high. System
++// default ThreadStackSize appears to be 512 which is too big.
++define_pd_global(intx, ThreadStackSize, 320);
++define_pd_global(intx, VMThreadStackSize, 512);
++#endif // AMD64
++
++define_pd_global(intx, CompilerThreadStackSize, 0);
++define_pd_global(intx, SurvivorRatio, 8);
++
++define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
++
++// Only used on 64 bit platforms
++define_pd_global(uintx, HeapBaseMinAddress, 2*G);
++// Only used on 64 bit Windows platforms
++define_pd_global(bool, UseVectoredExceptions, false);
++
++#endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp 2013-04-08 01:49:33.606321876 +0100
+@@ -0,0 +1,215 @@
++/*
++ * 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.
++ *
++ */
++
++#ifndef OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
++#define OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
++
++#include "runtime/atomic.hpp"
++#include "runtime/orderAccess.hpp"
++#include "vm_version_x86.hpp"
++
++// Implementation of class OrderAccess.
++
++inline void OrderAccess::loadload() { acquire(); }
++inline void OrderAccess::storestore() { release(); }
++inline void OrderAccess::loadstore() { acquire(); }
++inline void OrderAccess::storeload() { fence(); }
++
++inline void OrderAccess::acquire() {
++ volatile intptr_t local_dummy;
++#ifdef AMD64
++ __asm__ volatile ("movq 0(%%rsp), %0" : "=r" (local_dummy) : : "memory");
++#else
++ __asm__ volatile ("movl 0(%%esp),%0" : "=r" (local_dummy) : : "memory");
++#endif // AMD64
++}
++
++inline void OrderAccess::release() {
++ // Avoid hitting the same cache-line from
++ // different threads.
++ volatile jint local_dummy = 0;
++}
++
++inline void OrderAccess::fence() {
++ if (os::is_MP()) {
++ // always use locked addl since mfence is sometimes expensive
++#ifdef AMD64
++ __asm__ volatile ("lock; addl $0,0(%%rsp)" : : : "cc", "memory");
++#else
++ __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
++#endif
++ }
++}
++
++inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; }
++inline jshort OrderAccess::load_acquire(volatile jshort* p) { return *p; }
++inline jint OrderAccess::load_acquire(volatile jint* p) { return *p; }
++inline jlong OrderAccess::load_acquire(volatile jlong* p) { return Atomic::load(p); }
++inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { return *p; }
++inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; }
++inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; }
++inline julong OrderAccess::load_acquire(volatile julong* p) { return Atomic::load((volatile jlong*)p); }
++inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; }
++inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; }
++
++inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; }
++inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; }
++inline void* OrderAccess::load_ptr_acquire(const volatile void* p) { return *(void* const volatile *)p; }
++
++inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { *p = v; }
++inline void OrderAccess::release_store(volatile jshort* p, jshort v) { *p = v; }
++inline void OrderAccess::release_store(volatile jint* p, jint v) { *p = v; }
++inline void OrderAccess::release_store(volatile jlong* p, jlong v) { Atomic::store(v, p); }
++inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { *p = v; }
++inline void OrderAccess::release_store(volatile jushort* p, jushort v) { *p = v; }
++inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; }
++inline void OrderAccess::release_store(volatile julong* p, julong v) { Atomic::store((jlong)v, (volatile jlong*)p); }
++inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; }
++inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; }
++
++inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; }
++inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; }
++
++inline void OrderAccess::store_fence(jbyte* p, jbyte v) {
++ __asm__ volatile ( "xchgb (%2),%0"
++ : "=q" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++}
++inline void OrderAccess::store_fence(jshort* p, jshort v) {
++ __asm__ volatile ( "xchgw (%2),%0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++}
++inline void OrderAccess::store_fence(jint* p, jint v) {
++ __asm__ volatile ( "xchgl (%2),%0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++}
++
++inline void OrderAccess::store_fence(jlong* p, jlong v) {
++#ifdef AMD64
++ __asm__ __volatile__ ("xchgq (%2), %0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++#else
++ *p = v; fence();
++#endif // AMD64
++}
++
++// AMD64 copied the bodies for the the signed version. 32bit did this. As long as the
++// compiler does the inlining this is simpler.
++inline void OrderAccess::store_fence(jubyte* p, jubyte v) { store_fence((jbyte*)p, (jbyte)v); }
++inline void OrderAccess::store_fence(jushort* p, jushort v) { store_fence((jshort*)p, (jshort)v); }
++inline void OrderAccess::store_fence(juint* p, juint v) { store_fence((jint*)p, (jint)v); }
++inline void OrderAccess::store_fence(julong* p, julong v) { store_fence((jlong*)p, (jlong)v); }
++inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(jdouble* p, jdouble v) { *p = v; fence(); }
++
++inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) {
++#ifdef AMD64
++ __asm__ __volatile__ ("xchgq (%2), %0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++#else
++ store_fence((jint*)p, (jint)v);
++#endif // AMD64
++}
++
++inline void OrderAccess::store_ptr_fence(void** p, void* v) {
++#ifdef AMD64
++ __asm__ __volatile__ ("xchgq (%2), %0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++#else
++ store_fence((jint*)p, (jint)v);
++#endif // AMD64
++}
++
++// Must duplicate definitions instead of calling store_fence because we don't want to cast away volatile.
++inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) {
++ __asm__ volatile ( "xchgb (%2),%0"
++ : "=q" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++}
++inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) {
++ __asm__ volatile ( "xchgw (%2),%0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++}
++inline void OrderAccess::release_store_fence(volatile jint* p, jint v) {
++ __asm__ volatile ( "xchgl (%2),%0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++}
++
++inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) {
++#ifdef AMD64
++ __asm__ __volatile__ ( "xchgq (%2), %0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++#else
++ release_store(p, v); fence();
++#endif // AMD64
++}
++
++inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store_fence((volatile jbyte*)p, (jbyte)v); }
++inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store_fence((volatile jshort*)p, (jshort)v); }
++inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store_fence((volatile jint*)p, (jint)v); }
++inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
++
++inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
++inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); }
++
++inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
++#ifdef AMD64
++ __asm__ __volatile__ ( "xchgq (%2), %0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++#else
++ release_store_fence((volatile jint*)p, (jint)v);
++#endif // AMD64
++}
++inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) {
++#ifdef AMD64
++ __asm__ __volatile__ ( "xchgq (%2), %0"
++ : "=r" (v)
++ : "0" (v), "r" (p)
++ : "memory");
++#else
++ release_store_fence((volatile jint*)p, (jint)v);
++#endif // AMD64
++}
++
++#endif // OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,1124 @@
++/*
++ * Copyright (c) 1999, 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.
++ *
++ */
++
++// no precompiled headers
++#include "assembler_x86.inline.hpp"
++#include "classfile/classLoader.hpp"
++#include "classfile/systemDictionary.hpp"
++#include "classfile/vmSymbols.hpp"
++#include "code/icBuffer.hpp"
++#include "code/vtableStubs.hpp"
++#include "interpreter/interpreter.hpp"
++#include "jvm_bsd.h"
++#include "memory/allocation.inline.hpp"
++#include "mutex_bsd.inline.hpp"
++#include "nativeInst_x86.hpp"
++#include "os_share_bsd.hpp"
++#include "prims/jniFastGetField.hpp"
++#include "prims/jvm.h"
++#include "prims/jvm_misc.hpp"
++#include "runtime/arguments.hpp"
++#include "runtime/extendedPC.hpp"
++#include "runtime/frame.inline.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/java.hpp"
++#include "runtime/javaCalls.hpp"
++#include "runtime/mutexLocker.hpp"
++#include "runtime/osThread.hpp"
++#include "runtime/sharedRuntime.hpp"
++#include "runtime/stubRoutines.hpp"
++#include "runtime/timer.hpp"
++#include "thread_bsd.inline.hpp"
++#include "utilities/events.hpp"
++#include "utilities/vmError.hpp"
++#ifdef COMPILER1
++#include "c1/c1_Runtime1.hpp"
++#endif
++#ifdef COMPILER2
++#include "opto/runtime.hpp"
++#endif
++
++// put OS-includes here
++# include <sys/types.h>
++# include <sys/mman.h>
++# include <pthread.h>
++# include <signal.h>
++# include <errno.h>
++# include <dlfcn.h>
++# include <stdlib.h>
++# include <stdio.h>
++# include <unistd.h>
++# include <sys/resource.h>
++# include <pthread.h>
++# include <sys/stat.h>
++# include <sys/time.h>
++# include <sys/utsname.h>
++# include <sys/socket.h>
++# include <sys/wait.h>
++# include <pwd.h>
++# include <poll.h>
++#ifndef __OpenBSD__
++# include <ucontext.h>
++#endif
++
++#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
++# include <pthread_np.h>
++#endif
++
++#ifdef AMD64
++#define SPELL_REG_SP "rsp"
++#define SPELL_REG_FP "rbp"
++#else
++#define SPELL_REG_SP "esp"
++#define SPELL_REG_FP "ebp"
++#endif // AMD64
++
++#ifdef __FreeBSD__
++# define context_trapno uc_mcontext.mc_trapno
++# ifdef AMD64
++# define context_pc uc_mcontext.mc_rip
++# define context_sp uc_mcontext.mc_rsp
++# define context_fp uc_mcontext.mc_rbp
++# define context_rip uc_mcontext.mc_rip
++# define context_rsp uc_mcontext.mc_rsp
++# define context_rbp uc_mcontext.mc_rbp
++# define context_rax uc_mcontext.mc_rax
++# define context_rbx uc_mcontext.mc_rbx
++# define context_rcx uc_mcontext.mc_rcx
++# define context_rdx uc_mcontext.mc_rdx
++# define context_rsi uc_mcontext.mc_rsi
++# define context_rdi uc_mcontext.mc_rdi
++# define context_r8 uc_mcontext.mc_r8
++# define context_r9 uc_mcontext.mc_r9
++# define context_r10 uc_mcontext.mc_r10
++# define context_r11 uc_mcontext.mc_r11
++# define context_r12 uc_mcontext.mc_r12
++# define context_r13 uc_mcontext.mc_r13
++# define context_r14 uc_mcontext.mc_r14
++# define context_r15 uc_mcontext.mc_r15
++# define context_flags uc_mcontext.mc_flags
++# define context_err uc_mcontext.mc_err
++# else
++# define context_pc uc_mcontext.mc_eip
++# define context_sp uc_mcontext.mc_esp
++# define context_fp uc_mcontext.mc_ebp
++# define context_eip uc_mcontext.mc_eip
++# define context_esp uc_mcontext.mc_esp
++# define context_eax uc_mcontext.mc_eax
++# define context_ebx uc_mcontext.mc_ebx
++# define context_ecx uc_mcontext.mc_ecx
++# define context_edx uc_mcontext.mc_edx
++# define context_ebp uc_mcontext.mc_ebp
++# define context_esi uc_mcontext.mc_esi
++# define context_edi uc_mcontext.mc_edi
++# define context_eflags uc_mcontext.mc_eflags
++# define context_trapno uc_mcontext.mc_trapno
++# endif
++#endif
++
++#ifdef __APPLE__
++# if __DARWIN_UNIX03 && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
++ // 10.5 UNIX03 member name prefixes
++ #define DU3_PREFIX(s, m) __ ## s.__ ## m
++# else
++ #define DU3_PREFIX(s, m) s ## . ## m
++# endif
++
++# ifdef AMD64
++# define context_pc context_rip
++# define context_sp context_rsp
++# define context_fp context_rbp
++# define context_rip uc_mcontext->DU3_PREFIX(ss,rip)
++# define context_rsp uc_mcontext->DU3_PREFIX(ss,rsp)
++# define context_rax uc_mcontext->DU3_PREFIX(ss,rax)
++# define context_rbx uc_mcontext->DU3_PREFIX(ss,rbx)
++# define context_rcx uc_mcontext->DU3_PREFIX(ss,rcx)
++# define context_rdx uc_mcontext->DU3_PREFIX(ss,rdx)
++# define context_rbp uc_mcontext->DU3_PREFIX(ss,rbp)
++# define context_rsi uc_mcontext->DU3_PREFIX(ss,rsi)
++# define context_rdi uc_mcontext->DU3_PREFIX(ss,rdi)
++# define context_r8 uc_mcontext->DU3_PREFIX(ss,r8)
++# define context_r9 uc_mcontext->DU3_PREFIX(ss,r9)
++# define context_r10 uc_mcontext->DU3_PREFIX(ss,r10)
++# define context_r11 uc_mcontext->DU3_PREFIX(ss,r11)
++# define context_r12 uc_mcontext->DU3_PREFIX(ss,r12)
++# define context_r13 uc_mcontext->DU3_PREFIX(ss,r13)
++# define context_r14 uc_mcontext->DU3_PREFIX(ss,r14)
++# define context_r15 uc_mcontext->DU3_PREFIX(ss,r15)
++# define context_flags uc_mcontext->DU3_PREFIX(ss,rflags)
++# define context_trapno uc_mcontext->DU3_PREFIX(es,trapno)
++# define context_err uc_mcontext->DU3_PREFIX(es,err)
++# else
++# define context_pc context_eip
++# define context_sp context_esp
++# define context_fp context_ebp
++# define context_eip uc_mcontext->DU3_PREFIX(ss,eip)
++# define context_esp uc_mcontext->DU3_PREFIX(ss,esp)
++# define context_eax uc_mcontext->DU3_PREFIX(ss,eax)
++# define context_ebx uc_mcontext->DU3_PREFIX(ss,ebx)
++# define context_ecx uc_mcontext->DU3_PREFIX(ss,ecx)
++# define context_edx uc_mcontext->DU3_PREFIX(ss,edx)
++# define context_ebp uc_mcontext->DU3_PREFIX(ss,ebp)
++# define context_esi uc_mcontext->DU3_PREFIX(ss,esi)
++# define context_edi uc_mcontext->DU3_PREFIX(ss,edi)
++# define context_eflags uc_mcontext->DU3_PREFIX(ss,eflags)
++# define context_trapno uc_mcontext->DU3_PREFIX(es,trapno)
++# endif
++#endif
++
++#ifdef __OpenBSD__
++# define context_trapno sc_trapno
++# ifdef AMD64
++# define context_pc sc_rip
++# define context_sp sc_rsp
++# define context_fp sc_rbp
++# define context_rip sc_rip
++# define context_rsp sc_rsp
++# define context_rbp sc_rbp
++# define context_rax sc_rax
++# define context_rbx sc_rbx
++# define context_rcx sc_rcx
++# define context_rdx sc_rdx
++# define context_rsi sc_rsi
++# define context_rdi sc_rdi
++# define context_r8 sc_r8
++# define context_r9 sc_r9
++# define context_r10 sc_r10
++# define context_r11 sc_r11
++# define context_r12 sc_r12
++# define context_r13 sc_r13
++# define context_r14 sc_r14
++# define context_r15 sc_r15
++# define context_flags sc_rflags
++# define context_err sc_err
++# else
++# define context_pc sc_eip
++# define context_sp sc_esp
++# define context_fp sc_ebp
++# define context_eip sc_eip
++# define context_esp sc_esp
++# define context_eax sc_eax
++# define context_ebx sc_ebx
++# define context_ecx sc_ecx
++# define context_edx sc_edx
++# define context_ebp sc_ebp
++# define context_esi sc_esi
++# define context_edi sc_edi
++# define context_eflags sc_eflags
++# define context_trapno sc_trapno
++# endif
++#endif
++
++#ifdef __NetBSD__
++# define context_trapno uc_mcontext.__gregs[_REG_TRAPNO]
++# ifdef AMD64
++# define __register_t __greg_t
++# define context_pc uc_mcontext.__gregs[_REG_RIP]
++# define context_sp uc_mcontext.__gregs[_REG_URSP]
++# define context_fp uc_mcontext.__gregs[_REG_RBP]
++# define context_rip uc_mcontext.__gregs[_REG_RIP]
++# define context_rsp uc_mcontext.__gregs[_REG_URSP]
++# define context_rax uc_mcontext.__gregs[_REG_RAX]
++# define context_rbx uc_mcontext.__gregs[_REG_RBX]
++# define context_rcx uc_mcontext.__gregs[_REG_RCX]
++# define context_rdx uc_mcontext.__gregs[_REG_RDX]
++# define context_rbp uc_mcontext.__gregs[_REG_RBP]
++# define context_rsi uc_mcontext.__gregs[_REG_RSI]
++# define context_rdi uc_mcontext.__gregs[_REG_RDI]
++# define context_r8 uc_mcontext.__gregs[_REG_R8]
++# define context_r9 uc_mcontext.__gregs[_REG_R9]
++# define context_r10 uc_mcontext.__gregs[_REG_R10]
++# define context_r11 uc_mcontext.__gregs[_REG_R11]
++# define context_r12 uc_mcontext.__gregs[_REG_R12]
++# define context_r13 uc_mcontext.__gregs[_REG_R13]
++# define context_r14 uc_mcontext.__gregs[_REG_R14]
++# define context_r15 uc_mcontext.__gregs[_REG_R15]
++# define context_flags uc_mcontext.__gregs[_REG_RFL]
++# define context_err uc_mcontext.__gregs[_REG_ERR]
++# else
++# define context_pc uc_mcontext.__gregs[_REG_EIP]
++# define context_sp uc_mcontext.__gregs[_REG_UESP]
++# define context_fp uc_mcontext.__gregs[_REG_EBP]
++# define context_eip uc_mcontext.__gregs[_REG_EIP]
++# define context_esp uc_mcontext.__gregs[_REG_UESP]
++# define context_eax uc_mcontext.__gregs[_REG_EAX]
++# define context_ebx uc_mcontext.__gregs[_REG_EBX]
++# define context_ecx uc_mcontext.__gregs[_REG_ECX]
++# define context_edx uc_mcontext.__gregs[_REG_EDX]
++# define context_ebp uc_mcontext.__gregs[_REG_EBP]
++# define context_esi uc_mcontext.__gregs[_REG_ESI]
++# define context_edi uc_mcontext.__gregs[_REG_EDI]
++# define context_eflags uc_mcontext.__gregs[_REG_EFL]
++# define context_trapno uc_mcontext.__gregs[_REG_TRAPNO]
++# endif
++#endif
++
++address os::current_stack_pointer() {
++#ifdef SPARC_WORKS
++ register void *esp;
++ __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
++ return (address) ((char*)esp + sizeof(long)*2);
++#else
++ register void *esp __asm__ (SPELL_REG_SP);
++ return (address) esp;
++#endif
++}
++
++char* os::non_memory_address_word() {
++ // Must never look like an address returned by reserve_memory,
++ // even in its subfields (as defined by the CPU immediate fields,
++ // if the CPU splits constants across multiple instructions).
++
++ return (char*) -1;
++}
++
++void os::initialize_thread() {
++// Nothing to do.
++}
++
++address os::Bsd::ucontext_get_pc(ucontext_t * uc) {
++ return (address)uc->context_pc;
++}
++
++intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) {
++ return (intptr_t*)uc->context_sp;
++}
++
++intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) {
++ return (intptr_t*)uc->context_fp;
++}
++
++// For Forte Analyzer AsyncGetCallTrace profiling support - thread
++// is currently interrupted by SIGPROF.
++// os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
++// frames. Currently we don't do that on Bsd, so it's the same as
++// os::fetch_frame_from_context().
++ExtendedPC os::Bsd::fetch_frame_from_ucontext(Thread* thread,
++ ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
++
++ assert(thread != NULL, "just checking");
++ assert(ret_sp != NULL, "just checking");
++ assert(ret_fp != NULL, "just checking");
++
++ return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
++}
++
++ExtendedPC os::fetch_frame_from_context(void* ucVoid,
++ intptr_t** ret_sp, intptr_t** ret_fp) {
++
++ ExtendedPC epc;
++ ucontext_t* uc = (ucontext_t*)ucVoid;
++
++ if (uc != NULL) {
++ epc = ExtendedPC(os::Bsd::ucontext_get_pc(uc));
++ if (ret_sp) *ret_sp = os::Bsd::ucontext_get_sp(uc);
++ if (ret_fp) *ret_fp = os::Bsd::ucontext_get_fp(uc);
++ } else {
++ // construct empty ExtendedPC for return value checking
++ epc = ExtendedPC(NULL);
++ if (ret_sp) *ret_sp = (intptr_t *)NULL;
++ if (ret_fp) *ret_fp = (intptr_t *)NULL;
++ }
++
++ return epc;
++}
++
++frame os::fetch_frame_from_context(void* ucVoid) {
++ intptr_t* sp;
++ intptr_t* fp;
++ ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
++ return frame(sp, fp, epc.pc());
++}
++
++// By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get
++// turned off by -fomit-frame-pointer,
++frame os::get_sender_for_C_frame(frame* fr) {
++ return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
++}
++
++intptr_t* _get_previous_fp() {
++#ifdef SPARC_WORKS
++ register intptr_t **ebp;
++ __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
++#else
++ register intptr_t **ebp __asm__ (SPELL_REG_FP);
++#endif
++ return (intptr_t*) *ebp; // we want what it points to.
++}
++
++
++frame os::current_frame() {
++ intptr_t* fp = _get_previous_fp();
++ frame myframe((intptr_t*)os::current_stack_pointer(),
++ (intptr_t*)fp,
++ CAST_FROM_FN_PTR(address, os::current_frame));
++ if (os::is_first_C_frame(&myframe)) {
++ // stack is not walkable
++ return frame(NULL, NULL, NULL);
++ } else {
++ return os::get_sender_for_C_frame(&myframe);
++ }
++}
++
++// Utility functions
++
++// From IA32 System Programming Guide
++enum {
++ trap_page_fault = 0xE
++};
++
++extern "C" void Fetch32PFI () ;
++extern "C" void Fetch32Resume () ;
++#ifdef AMD64
++extern "C" void FetchNPFI () ;
++extern "C" void FetchNResume () ;
++#endif // AMD64
++
++extern "C" JNIEXPORT int
++JVM_handle_bsd_signal(int sig,
++ siginfo_t* info,
++ void* ucVoid,
++ int abort_if_unrecognized) {
++ ucontext_t* uc = (ucontext_t*) ucVoid;
++
++ Thread* t = ThreadLocalStorage::get_thread_slow();
++
++ SignalHandlerMark shm(t);
++
++ // Note: it's not uncommon that JNI code uses signal/sigset to install
++ // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
++ // or have a SIGILL handler when detecting CPU type). When that happens,
++ // JVM_handle_bsd_signal() might be invoked with junk info/ucVoid. To
++ // avoid unnecessary crash when libjsig is not preloaded, try handle signals
++ // that do not require siginfo/ucontext first.
++
++ if (sig == SIGPIPE || sig == SIGXFSZ) {
++ // allow chained handler to go first
++ if (os::Bsd::chained_handler(sig, info, ucVoid)) {
++ return true;
++ } else {
++ if (PrintMiscellaneous && (WizardMode || Verbose)) {
++ char buf[64];
++ warning("Ignoring %s - see bugs 4229104 or 646499219",
++ os::exception_name(sig, buf, sizeof(buf)));
++ }
++ return true;
++ }
++ }
++
++ JavaThread* thread = NULL;
++ VMThread* vmthread = NULL;
++ if (os::Bsd::signal_handlers_are_installed) {
++ if (t != NULL ){
++ if(t->is_Java_thread()) {
++ thread = (JavaThread*)t;
++ }
++ else if(t->is_VM_thread()){
++ vmthread = (VMThread *)t;
++ }
++ }
++ }
++/*
++ NOTE: does not seem to work on bsd.
++ if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
++ // can't decode this kind of signal
++ info = NULL;
++ } else {
++ assert(sig == info->si_signo, "bad siginfo");
++ }
++*/
++ // decide if this trap can be handled by a stub
++ address stub = NULL;
++
++ address pc = NULL;
++
++ //%note os_trap_1
++ if (info != NULL && uc != NULL && thread != NULL) {
++ pc = (address) os::Bsd::ucontext_get_pc(uc);
++
++ if (pc == (address) Fetch32PFI) {
++ uc->context_pc = intptr_t(Fetch32Resume) ;
++ return 1 ;
++ }
++#ifdef AMD64
++ if (pc == (address) FetchNPFI) {
++ uc->context_pc = intptr_t (FetchNResume) ;
++ return 1 ;
++ }
++#endif // AMD64
++
++ // Handle ALL stack overflow variations here
++ if (sig == SIGSEGV || sig == SIGBUS) {
++ address addr = (address) info->si_addr;
++
++ // check if fault address is within thread stack
++ if (addr < thread->stack_base() &&
++ addr >= thread->stack_base() - thread->stack_size()) {
++ // stack overflow
++ if (thread->in_stack_yellow_zone(addr)) {
++ thread->disable_stack_yellow_zone();
++ if (thread->thread_state() == _thread_in_Java) {
++ // Throw a stack overflow exception. Guard pages will be reenabled
++ // while unwinding the stack.
++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
++ } else {
++ // Thread was in the vm or native code. Return and try to finish.
++ return 1;
++ }
++ } else if (thread->in_stack_red_zone(addr)) {
++ // Fatal red zone violation. Disable the guard pages and fall through
++ // to handle_unexpected_exception way down below.
++ thread->disable_stack_red_zone();
++ tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
++#ifndef _ALLBSD_SOURCE
++ } else {
++ // Accessing stack address below sp may cause SEGV if current
++ // thread has MAP_GROWSDOWN stack. This should only happen when
++ // current thread was created by user code with MAP_GROWSDOWN flag
++ // and then attached to VM. See notes in os_bsd.cpp.
++ if (thread->osthread()->expanding_stack() == 0) {
++ thread->osthread()->set_expanding_stack();
++ if (os::Bsd::manually_expand_stack(thread, addr)) {
++ thread->osthread()->clear_expanding_stack();
++ return 1;
++ }
++ thread->osthread()->clear_expanding_stack();
++ } else {
++ fatal("recursive segv. expanding stack.");
++ }
++#endif
++ }
++ }
++ }
++
++ if (thread->thread_state() == _thread_in_Java) {
++ // Java thread running in Java code => find exception handler if any
++ // a fault inside compiled code, the interpreter, or a stub
++
++ if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) {
++ stub = SharedRuntime::get_poll_stub(pc);
++#if defined(__APPLE__) && !defined(AMD64)
++ // 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions.
++ // Catching SIGBUS here prevents the implicit SIGBUS NULL check below from
++ // being called, so only do so if the implicit NULL check is not necessary.
++ } else if (sig == SIGBUS && MacroAssembler::needs_explicit_null_check((int)info->si_addr)) {
++#else
++ } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
++#endif
++ // BugId 4454115: A read from a MappedByteBuffer can fault
++ // here if the underlying file has been truncated.
++ // Do not crash the VM in such a case.
++ CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
++ nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
++ if (nm != NULL && nm->has_unsafe_access()) {
++ stub = StubRoutines::handler_for_unsafe_access();
++ }
++ }
++ else
++
++#ifdef AMD64
++ if (sig == SIGFPE &&
++ (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) {
++ stub =
++ SharedRuntime::
++ continuation_for_implicit_exception(thread,
++ pc,
++ SharedRuntime::
++ IMPLICIT_DIVIDE_BY_ZERO);
++#ifdef __APPLE__
++ } else if (sig == SIGFPE && info->si_code == FPE_NOOP) {
++ int op = pc[0];
++
++ // Skip REX
++ if ((pc[0] & 0xf0) == 0x40) {
++ op = pc[1];
++ } else {
++ op = pc[0];
++ }
++
++ // Check for IDIV
++ if (op == 0xF7) {
++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime:: IMPLICIT_DIVIDE_BY_ZERO);
++ } else {
++ // TODO: handle more cases if we are using other x86 instructions
++ // that can generate SIGFPE signal.
++ tty->print_cr("unknown opcode 0x%X with SIGFPE.", op);
++ fatal("please update this code.");
++ }
++#endif /* __APPLE__ */
++
++#else
++ if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) {
++ // HACK: si_code does not work on bsd 2.2.12-20!!!
++ int op = pc[0];
++ if (op == 0xDB) {
++ // FIST
++ // TODO: The encoding of D2I in i486.ad can cause an exception
++ // prior to the fist instruction if there was an invalid operation
++ // pending. We want to dismiss that exception. From the win_32
++ // side it also seems that if it really was the fist causing
++ // the exception that we do the d2i by hand with different
++ // rounding. Seems kind of weird.
++ // NOTE: that we take the exception at the NEXT floating point instruction.
++ assert(pc[0] == 0xDB, "not a FIST opcode");
++ assert(pc[1] == 0x14, "not a FIST opcode");
++ assert(pc[2] == 0x24, "not a FIST opcode");
++ return true;
++ } else if (op == 0xF7) {
++ // IDIV
++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
++ } else {
++ // TODO: handle more cases if we are using other x86 instructions
++ // that can generate SIGFPE signal on bsd.
++ tty->print_cr("unknown opcode 0x%X with SIGFPE.", op);
++ fatal("please update this code.");
++ }
++#endif // AMD64
++ } else if ((sig == SIGSEGV || sig == SIGBUS) &&
++ !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
++ // Determination of interpreter/vtable stub/compiled code null exception
++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
++ }
++ } else if (thread->thread_state() == _thread_in_vm &&
++ sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
++ thread->doing_unsafe_access()) {
++ stub = StubRoutines::handler_for_unsafe_access();
++ }
++
++ // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
++ // and the heap gets shrunk before the field access.
++ if ((sig == SIGSEGV) || (sig == SIGBUS)) {
++ address addr = JNI_FastGetField::find_slowcase_pc(pc);
++ if (addr != (address)-1) {
++ stub = addr;
++ }
++ }
++
++ // Check to see if we caught the safepoint code in the
++ // process 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 || sig == SIGBUS) &&
++ os::is_memory_serialize_page(thread, (address) info->si_addr)) {
++ // Block current thread until the memory serialize page permission restored.
++ os::block_on_serialize_page_trap();
++ return true;
++ }
++ }
++
++#ifndef AMD64
++ // Execution protection violation
++ //
++ // This should be kept as the last step in the triage. We don't
++ // have a dedicated trap number for a no-execute fault, so be
++ // conservative and allow other handlers the first shot.
++ //
++ // Note: We don't test that info->si_code == SEGV_ACCERR here.
++ // this si_code is so generic that it is almost meaningless; and
++ // the si_code for this condition may change in the future.
++ // Furthermore, a false-positive should be harmless.
++ if (UnguardOnExecutionViolation > 0 &&
++ (sig == SIGSEGV || sig == SIGBUS) &&
++ uc->context_trapno == trap_page_fault) {
++ int page_size = os::vm_page_size();
++ address addr = (address) info->si_addr;
++ address pc = os::Bsd::ucontext_get_pc(uc);
++ // Make sure the pc and the faulting address are sane.
++ //
++ // If an instruction spans a page boundary, and the page containing
++ // the beginning of the instruction is executable but the following
++ // page is not, the pc and the faulting address might be slightly
++ // different - we still want to unguard the 2nd page in this case.
++ //
++ // 15 bytes seems to be a (very) safe value for max instruction size.
++ bool pc_is_near_addr =
++ (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
++ bool instr_spans_page_boundary =
++ (align_size_down((intptr_t) pc ^ (intptr_t) addr,
++ (intptr_t) page_size) > 0);
++
++ if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
++ static volatile address last_addr =
++ (address) os::non_memory_address_word();
++
++ // In conservative mode, don't unguard unless the address is in the VM
++ if (addr != last_addr &&
++ (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
++
++ // Set memory to RWX and retry
++ address page_start =
++ (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
++ bool res = os::protect_memory((char*) page_start, page_size,
++ os::MEM_PROT_RWX);
++
++ if (PrintMiscellaneous && Verbose) {
++ char buf[256];
++ jio_snprintf(buf, sizeof(buf), "Execution protection violation "
++ "at " INTPTR_FORMAT
++ ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
++ page_start, (res ? "success" : "failed"), errno);
++ tty->print_raw_cr(buf);
++ }
++ stub = pc;
++
++ // Set last_addr so if we fault again at the same address, we don't end
++ // up in an endless loop.
++ //
++ // There are two potential complications here. Two threads trapping at
++ // the same address at the same time could cause one of the threads to
++ // think it already unguarded, and abort the VM. Likely very rare.
++ //
++ // The other race involves two threads alternately trapping at
++ // different addresses and failing to unguard the page, resulting in
++ // an endless loop. This condition is probably even more unlikely than
++ // the first.
++ //
++ // Although both cases could be avoided by using locks or thread local
++ // last_addr, these solutions are unnecessary complication: this
++ // handler is a best-effort safety net, not a complete solution. It is
++ // disabled by default and should only be used as a workaround in case
++ // we missed any no-execute-unsafe VM code.
++
++ last_addr = addr;
++ }
++ }
++ }
++#endif // !AMD64
++
++ if (stub != NULL) {
++ // save all thread context in case we need to restore it
++ if (thread != NULL) thread->set_saved_exception_pc(pc);
++
++ uc->context_pc = (intptr_t)stub;
++ return true;
++ }
++
++ // signal-chaining
++ if (os::Bsd::chained_handler(sig, info, ucVoid)) {
++ return true;
++ }
++
++ if (!abort_if_unrecognized) {
++ // caller wants another chance, so give it to him
++ return false;
++ }
++
++ if (pc == NULL && uc != NULL) {
++ pc = os::Bsd::ucontext_get_pc(uc);
++ }
++
++ // unmask current signal
++ sigset_t newset;
++ sigemptyset(&newset);
++ sigaddset(&newset, sig);
++ sigprocmask(SIG_UNBLOCK, &newset, NULL);
++
++ VMError err(t, sig, pc, info, ucVoid);
++ err.report_and_die();
++
++ ShouldNotReachHere();
++}
++
++#ifdef _ALLBSD_SOURCE
++// From solaris_i486.s ported to bsd_i486.s
++extern "C" void fixcw();
++#endif
++
++void os::Bsd::init_thread_fpu_state(void) {
++#ifndef AMD64
++# ifdef _ALLBSD_SOURCE
++ // Set fpu to 53 bit precision. This happens too early to use a stub.
++ fixcw();
++# else
++ // set fpu to 53 bit precision
++ set_fpu_control_word(0x27f);
++# endif
++#endif // !AMD64
++}
++
++#ifndef _ALLBSD_SOURCE
++int os::Bsd::get_fpu_control_word(void) {
++#ifdef AMD64
++ return 0;
++#else
++ int fpu_control;
++ _FPU_GETCW(fpu_control);
++ return fpu_control & 0xffff;
++#endif // AMD64
++}
++
++void os::Bsd::set_fpu_control_word(int fpu_control) {
++#ifndef AMD64
++ _FPU_SETCW(fpu_control);
++#endif // !AMD64
++}
++#endif
++
++// Check that the bsd kernel version is 2.4 or higher since earlier
++// versions do not support SSE without patches.
++bool os::supports_sse() {
++#if defined(AMD64) || defined(_ALLBSD_SOURCE)
++ return true;
++#else
++ struct utsname uts;
++ if( uname(&uts) != 0 ) return false; // uname fails?
++ char *minor_string;
++ int major = strtol(uts.release,&minor_string,10);
++ int minor = strtol(minor_string+1,NULL,10);
++ bool result = (major > 2 || (major==2 && minor >= 4));
++#ifndef PRODUCT
++ if (PrintMiscellaneous && Verbose) {
++ tty->print("OS version is %d.%d, which %s support SSE/SSE2\n",
++ major,minor, result ? "DOES" : "does NOT");
++ }
++#endif
++ return result;
++#endif // AMD64
++}
++
++bool os::is_allocatable(size_t bytes) {
++#ifdef AMD64
++ // unused on amd64?
++ return true;
++#else
++
++ if (bytes < 2 * G) {
++ return true;
++ }
++
++ char* addr = reserve_memory(bytes, NULL);
++
++ if (addr != NULL) {
++ release_memory(addr, bytes);
++ }
++
++ return addr != NULL;
++#endif // AMD64
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// thread stack
++
++#ifdef AMD64
++size_t os::Bsd::min_stack_allowed = 64 * K;
++
++// amd64: pthread on amd64 is always in floating stack mode
++bool os::Bsd::supports_variable_stack_size() { return true; }
++#else
++size_t os::Bsd::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
++
++#ifdef __GNUC__
++#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
++#endif
++
++#ifdef _ALLBSD_SOURCE
++bool os::Bsd::supports_variable_stack_size() { return true; }
++#else
++// Test if pthread library can support variable thread stack size. BsdThreads
++// in fixed stack mode allocates 2M fixed slot for each thread. BsdThreads
++// in floating stack mode and NPTL support variable stack size.
++bool os::Bsd::supports_variable_stack_size() {
++ if (os::Bsd::is_NPTL()) {
++ // NPTL, yes
++ return true;
++
++ } else {
++ // Note: We can't control default stack size when creating a thread.
++ // If we use non-default stack size (pthread_attr_setstacksize), both
++ // floating stack and non-floating stack BsdThreads will return the
++ // same value. This makes it impossible to implement this function by
++ // detecting thread stack size directly.
++ //
++ // An alternative approach is to check %gs. Fixed-stack BsdThreads
++ // do not use %gs, so its value is 0. Floating-stack BsdThreads use
++ // %gs (either as LDT selector or GDT selector, depending on kernel)
++ // to access thread specific data.
++ //
++ // Note that %gs is a reserved glibc register since early 2001, so
++ // applications are not allowed to change its value (Ulrich Drepper from
++ // Redhat confirmed that all known offenders have been modified to use
++ // either %fs or TSD). In the worst case scenario, when VM is embedded in
++ // a native application that plays with %gs, we might see non-zero %gs
++ // even BsdThreads is running in fixed stack mode. As the result, we'll
++ // return true and skip _thread_safety_check(), so we may not be able to
++ // detect stack-heap collisions. But otherwise it's harmless.
++ //
++#ifdef __GNUC__
++ return (GET_GS() != 0);
++#else
++ return false;
++#endif
++ }
++}
++#endif
++#endif // AMD64
++
++// return default stack size for thr_type
++size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
++ // default stack size (compiler thread needs larger stack)
++#ifdef AMD64
++ size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
++#else
++ size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
++#endif // AMD64
++ return s;
++}
++
++size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
++ // Creating guard page is very expensive. Java thread has HotSpot
++ // guard page, only enable glibc guard page for non-Java threads.
++ return (thr_type == java_thread ? 0 : page_size());
++}
++
++// Java thread:
++//
++// Low memory addresses
++// +------------------------+
++// | |\ JavaThread created by VM does not have glibc
++// | glibc guard page | - guard, attached Java thread usually has
++// | |/ 1 page glibc guard.
++// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
++// | |\
++// | HotSpot Guard Pages | - red and yellow pages
++// | |/
++// +------------------------+ JavaThread::stack_yellow_zone_base()
++// | |\
++// | Normal Stack | -
++// | |/
++// P2 +------------------------+ Thread::stack_base()
++//
++// Non-Java thread:
++//
++// Low memory addresses
++// +------------------------+
++// | |\
++// | glibc guard page | - usually 1 page
++// | |/
++// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
++// | |\
++// | Normal Stack | -
++// | |/
++// P2 +------------------------+ Thread::stack_base()
++//
++// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
++// pthread_attr_getstack()
++
++static void current_stack_region(address * bottom, size_t * size) {
++#ifdef __APPLE__
++ pthread_t self = pthread_self();
++ void *stacktop = pthread_get_stackaddr_np(self);
++ *size = pthread_get_stacksize_np(self);
++ *bottom = (address) stacktop - *size;
++#elif defined(__OpenBSD__)
++ stack_t ss;
++ int rslt = pthread_stackseg_np(pthread_self(), &ss);
++
++ if (rslt != 0)
++ fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt));
++
++ *bottom = (address)((char *)ss.ss_sp - ss.ss_size);
++ *size = ss.ss_size;
++#elif defined(_ALLBSD_SOURCE)
++ pthread_attr_t attr;
++
++ int rslt = pthread_attr_init(&attr);
++
++ // 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));
++
++ rslt = pthread_attr_get_np(pthread_self(), &attr);
++
++ if (rslt != 0)
++ fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt));
++
++ if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 ||
++ pthread_attr_getstacksize(&attr, size) != 0) {
++ fatal("Can not locate current stack attributes!");
++ }
++
++ pthread_attr_destroy(&attr);
++#else
++ if (os::Bsd::is_initial_thread()) {
++ // initial thread needs special handling because pthread_getattr_np()
++ // may return bogus value.
++ *bottom = os::Bsd::initial_thread_stack_bottom();
++ *size = os::Bsd::initial_thread_stack_size();
++ } else {
++ pthread_attr_t attr;
++
++ int rslt = pthread_getattr_np(pthread_self(), &attr);
++
++ // JVM needs to know exact stack location, abort if it fails
++ if (rslt != 0) {
++ if (rslt == ENOMEM) {
++ vm_exit_out_of_memory(0, "pthread_getattr_np");
++ } else {
++ fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
++ }
++ }
++
++ if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
++ fatal("Can not locate current stack attributes!");
++ }
++
++ pthread_attr_destroy(&attr);
++
++ }
++#endif
++ assert(os::current_stack_pointer() >= *bottom &&
++ os::current_stack_pointer() < *bottom + *size, "just checking");
++}
++
++address os::current_stack_base() {
++ address bottom;
++ size_t size;
++ current_stack_region(&bottom, &size);
++ return (bottom + size);
++}
++
++size_t os::current_stack_size() {
++ // stack size includes normal stack and HotSpot guard pages
++ address bottom;
++ size_t size;
++ current_stack_region(&bottom, &size);
++ return size;
++}
++
++/////////////////////////////////////////////////////////////////////////////
++// helper functions for fatal error handler
++
++void os::print_context(outputStream *st, void *context) {
++ if (context == NULL) return;
++
++ ucontext_t *uc = (ucontext_t*)context;
++ st->print_cr("Registers:");
++#ifdef AMD64
++ st->print( "RAX=" INTPTR_FORMAT, uc->context_rax);
++ st->print(", RBX=" INTPTR_FORMAT, uc->context_rbx);
++ st->print(", RCX=" INTPTR_FORMAT, uc->context_rcx);
++ st->print(", RDX=" INTPTR_FORMAT, uc->context_rdx);
++ st->cr();
++ st->print( "RSP=" INTPTR_FORMAT, uc->context_rsp);
++ st->print(", RBP=" INTPTR_FORMAT, uc->context_rbp);
++ st->print(", RSI=" INTPTR_FORMAT, uc->context_rsi);
++ st->print(", RDI=" INTPTR_FORMAT, uc->context_rdi);
++ st->cr();
++ st->print( "R8 =" INTPTR_FORMAT, uc->context_r8);
++ st->print(", R9 =" INTPTR_FORMAT, uc->context_r9);
++ st->print(", R10=" INTPTR_FORMAT, uc->context_r10);
++ st->print(", R11=" INTPTR_FORMAT, uc->context_r11);
++ st->cr();
++ st->print( "R12=" INTPTR_FORMAT, uc->context_r12);
++ st->print(", R13=" INTPTR_FORMAT, uc->context_r13);
++ st->print(", R14=" INTPTR_FORMAT, uc->context_r14);
++ st->print(", R15=" INTPTR_FORMAT, uc->context_r15);
++ st->cr();
++ st->print( "RIP=" INTPTR_FORMAT, uc->context_rip);
++ st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_flags);
++ st->print(", ERR=" INTPTR_FORMAT, uc->context_err);
++ st->cr();
++ st->print(" TRAPNO=" INTPTR_FORMAT, uc->context_trapno);
++#else
++ st->print( "EAX=" INTPTR_FORMAT, uc->context_eax);
++ st->print(", EBX=" INTPTR_FORMAT, uc->context_ebx);
++ st->print(", ECX=" INTPTR_FORMAT, uc->context_ecx);
++ st->print(", EDX=" INTPTR_FORMAT, uc->context_edx);
++ st->cr();
++ st->print( "ESP=" INTPTR_FORMAT, uc->context_esp);
++ st->print(", EBP=" INTPTR_FORMAT, uc->context_ebp);
++ st->print(", ESI=" INTPTR_FORMAT, uc->context_esi);
++ st->print(", EDI=" INTPTR_FORMAT, uc->context_edi);
++ st->cr();
++ st->print( "EIP=" INTPTR_FORMAT, uc->context_eip);
++ st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_eflags);
++#endif // AMD64
++ st->cr();
++ st->cr();
++
++ intptr_t *sp = (intptr_t *)os::Bsd::ucontext_get_sp(uc);
++ st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
++ print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
++ st->cr();
++
++ // Note: it may be unsafe to inspect memory near pc. For example, pc may
++ // point to garbage if entry point in an nmethod is corrupted. Leave
++ // this at the end, and hope for the best.
++ address pc = os::Bsd::ucontext_get_pc(uc);
++ st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
++ print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
++}
++
++void os::print_register_info(outputStream *st, void *context) {
++ if (context == NULL) return;
++
++ ucontext_t *uc = (ucontext_t*)context;
++
++ st->print_cr("Register to memory mapping:");
++ st->cr();
++
++ // this is horrendously verbose but the layout of the registers in the
++ // context does not match how we defined our abstract Register set, so
++ // we can't just iterate through the gregs area
++
++ // this is only for the "general purpose" registers
++
++#ifdef AMD64
++ st->print("RAX="); print_location(st, uc->context_rax);
++ st->print("RBX="); print_location(st, uc->context_rbx);
++ st->print("RCX="); print_location(st, uc->context_rcx);
++ st->print("RDX="); print_location(st, uc->context_rdx);
++ st->print("RSP="); print_location(st, uc->context_rsp);
++ st->print("RBP="); print_location(st, uc->context_rbp);
++ st->print("RSI="); print_location(st, uc->context_rsi);
++ st->print("RDI="); print_location(st, uc->context_rdi);
++ st->print("R8 ="); print_location(st, uc->context_r8);
++ st->print("R9 ="); print_location(st, uc->context_r9);
++ st->print("R10="); print_location(st, uc->context_r10);
++ st->print("R11="); print_location(st, uc->context_r11);
++ st->print("R12="); print_location(st, uc->context_r12);
++ st->print("R13="); print_location(st, uc->context_r13);
++ st->print("R14="); print_location(st, uc->context_r14);
++ st->print("R15="); print_location(st, uc->context_r15);
++#else
++ st->print("EAX="); print_location(st, uc->context_eax);
++ st->print("EBX="); print_location(st, uc->context_ebx);
++ st->print("ECX="); print_location(st, uc->context_ecx);
++ st->print("EDX="); print_location(st, uc->context_edx);
++ st->print("ESP="); print_location(st, uc->context_esp);
++ st->print("EBP="); print_location(st, uc->context_ebp);
++ st->print("ESI="); print_location(st, uc->context_esi);
++ st->print("EDI="); print_location(st, uc->context_edi);
++#endif // AMD64
++
++ st->cr();
++}
++
++void os::setup_fpu() {
++#ifndef AMD64
++ address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std();
++ __asm__ volatile ( "fldcw (%0)" :
++ : "r" (fpu_cntrl) : "memory");
++#endif // !AMD64
++}
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 1999, 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_CPU_BSD_X86_VM_OS_BSD_X86_HPP
++#define OS_CPU_BSD_X86_VM_OS_BSD_X86_HPP
++
++ static void setup_fpu();
++ static bool supports_sse();
++
++ static bool is_allocatable(size_t bytes);
++
++ // Used to register dynamic code cache area with the OS
++ // Note: Currently only used in 64 bit Windows implementations
++ static bool register_code_area(char *low, char *high) { return true; }
++
++#endif // OS_CPU_BSD_X86_VM_OS_BSD_X86_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/prefetch_bsd_x86.inline.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/prefetch_bsd_x86.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/prefetch_bsd_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/prefetch_bsd_x86.inline.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,47 @@
++/*
++ * 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_CPU_BSD_X86_VM_PREFETCH_BSD_X86_INLINE_HPP
++#define OS_CPU_BSD_X86_VM_PREFETCH_BSD_X86_INLINE_HPP
++
++#include "runtime/prefetch.hpp"
++
++
++inline void Prefetch::read (void *loc, intx interval) {
++#ifdef AMD64
++ __asm__ ("prefetcht0 (%0,%1,1)" : : "r" (loc), "r" (interval));
++#endif // AMD64
++}
++
++inline void Prefetch::write(void *loc, intx interval) {
++#ifdef AMD64
++
++ // Do not use the 3dnow prefetchw instruction. It isn't supported on em64t.
++ // __asm__ ("prefetchw (%0,%1,1)" : : "r" (loc), "r" (interval));
++ __asm__ ("prefetcht0 (%0,%1,1)" : : "r" (loc), "r" (interval));
++
++#endif // AMD64
++}
++
++#endif // OS_CPU_BSD_X86_VM_PREFETCH_BSD_X86_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,84 @@
++/*
++ * 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 "precompiled.hpp"
++#include "runtime/frame.inline.hpp"
++#include "thread_bsd.inline.hpp"
++
++// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
++// currently interrupted by SIGPROF
++bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
++ void* ucontext, bool isInJava) {
++
++ assert(Thread::current() == this, "caller must be current thread");
++ assert(this->is_Java_thread(), "must be JavaThread");
++
++ JavaThread* jt = (JavaThread *)this;
++
++ // If we have a last_Java_frame, then we should use it even if
++ // isInJava == true. It should be more reliable than ucontext info.
++ if (jt->has_last_Java_frame()) {
++ *fr_addr = jt->pd_last_frame();
++ return true;
++ }
++
++ // At this point, we don't have a last_Java_frame, so
++ // we try to glean some information out of the ucontext
++ // if we were running Java code when SIGPROF came in.
++ if (isInJava) {
++ ucontext_t* uc = (ucontext_t*) ucontext;
++
++ intptr_t* ret_fp;
++ intptr_t* ret_sp;
++ ExtendedPC addr = os::Bsd::fetch_frame_from_ucontext(this, uc,
++ &ret_sp, &ret_fp);
++ if (addr.pc() == NULL || ret_sp == NULL ) {
++ // ucontext wasn't useful
++ return false;
++ }
++
++ frame ret_frame(ret_sp, ret_fp, addr.pc());
++ if (!ret_frame.safe_for_sender(jt)) {
++#ifdef COMPILER2
++ // C2 uses ebp as a general register see if NULL fp helps
++ frame ret_frame2(ret_sp, NULL, addr.pc());
++ if (!ret_frame2.safe_for_sender(jt)) {
++ // nothing else to try if the frame isn't good
++ return false;
++ }
++ ret_frame = ret_frame2;
++#else
++ // nothing else to try if the frame isn't good
++ return false;
++#endif /* COMPILER2 */
++ }
++ *fr_addr = ret_frame;
++ return true;
++ }
++
++ // nothing else to try
++ return false;
++}
++
++void JavaThread::cache_global_variables() { }
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (c) 2000, 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_CPU_BSD_X86_VM_THREAD_BSD_X86_HPP
++#define OS_CPU_BSD_X86_VM_THREAD_BSD_X86_HPP
++
++ private:
++ void pd_initialize() {
++ _anchor.clear();
++ }
++
++ frame pd_last_frame() {
++ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
++ if (_anchor.last_Java_pc() != NULL) {
++ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
++ } else {
++ // This will pick up pc from sp
++ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp());
++ }
++ }
++
++ public:
++ // Mutators are highly dangerous....
++ intptr_t* last_Java_fp() { return _anchor.last_Java_fp(); }
++ void set_last_Java_fp(intptr_t* fp) { _anchor.set_last_Java_fp(fp); }
++
++ void set_base_of_stack_pointer(intptr_t* base_sp) {
++ }
++
++ static ByteSize last_Java_fp_offset() {
++ return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset();
++ }
++
++ intptr_t* base_of_stack_pointer() {
++ return NULL;
++ }
++ void record_base_of_stack_pointer() {
++ }
++
++ bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
++ bool isInJava);
++
++ // These routines are only used on cpu architectures that
++ // have separate register stacks (Itanium).
++ static bool register_stack_overflow() { return false; }
++ static void enable_register_stack_guard() {}
++ static void disable_register_stack_guard() {}
++
++#endif // OS_CPU_BSD_X86_VM_THREAD_BSD_X86_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 1999, 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 "precompiled.hpp"
++#include "runtime/threadLocalStorage.hpp"
++#include "thread_bsd.inline.hpp"
++
++// Map stack pointer (%esp) to thread pointer for faster TLS access
++//
++// Here we use a flat table for better performance. Getting current thread
++// is down to one memory access (read _sp_map[%esp>>12]) in generated code
++// and two in runtime code (-fPIC code needs an extra load for _sp_map).
++//
++// This code assumes stack page is not shared by different threads. It works
++// in 32-bit VM when page size is 4K (or a multiple of 4K, if that matters).
++//
++// Notice that _sp_map is allocated in the bss segment, which is ZFOD
++// (zero-fill-on-demand). While it reserves 4M address space upfront,
++// actual memory pages are committed on demand.
++//
++// If an application creates and destroys a lot of threads, usually the
++// stack space freed by a thread will soon get reused by new thread
++// (this is especially true in NPTL or BsdThreads in fixed-stack mode).
++// No memory page in _sp_map is wasted.
++//
++// However, it's still possible that we might end up populating &
++// committing a large fraction of the 4M table over time, but the actual
++// amount of live data in the table could be quite small. The max wastage
++// is less than 4M bytes. If it becomes an issue, we could use madvise()
++// with MADV_DONTNEED to reclaim unused (i.e. all-zero) pages in _sp_map.
++// MADV_DONTNEED on Bsd keeps the virtual memory mapping, but zaps the
++// physical memory page (i.e. similar to MADV_FREE on Solaris).
++
++#ifndef AMD64
++Thread* ThreadLocalStorage::_sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
++#endif // !AMD64
++
++void ThreadLocalStorage::generate_code_for_get_thread() {
++ // nothing we can do here for user-level thread
++}
++
++void ThreadLocalStorage::pd_init() {
++#ifndef AMD64
++ assert(align_size_down(os::vm_page_size(), PAGE_SIZE) == os::vm_page_size(),
++ "page size must be multiple of PAGE_SIZE");
++#endif // !AMD64
++}
++
++void ThreadLocalStorage::pd_set_thread(Thread* thread) {
++ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
++
++#ifndef AMD64
++ address stack_top = os::current_stack_base();
++ size_t stack_size = os::current_stack_size();
++
++ for (address p = stack_top - stack_size; p < stack_top; p += PAGE_SIZE) {
++ // pd_set_thread() is called with non-NULL value when a new thread is
++ // created/attached, or with NULL value when a thread is about to exit.
++ // If both "thread" and the corresponding _sp_map[] entry are non-NULL,
++ // they should have the same value. Otherwise it might indicate that the
++ // stack page is shared by multiple threads. However, a more likely cause
++ // for this assertion to fail is that an attached thread exited without
++ // detaching itself from VM, which is a program error and could cause VM
++ // to crash.
++ assert(thread == NULL || _sp_map[(uintptr_t)p >> PAGE_SHIFT] == NULL ||
++ thread == _sp_map[(uintptr_t)p >> PAGE_SHIFT],
++ "thread exited without detaching from VM??");
++ _sp_map[(uintptr_t)p >> PAGE_SHIFT] = thread;
++ }
++#endif // !AMD64
++}
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 1999, 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_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
++#define OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
++
++ // Processor dependent parts of ThreadLocalStorage
++
++#ifndef AMD64
++ // map stack pointer to thread pointer - see notes in threadLS_bsd_x86.cpp
++ #define SP_BITLENGTH 32
++#ifndef PAGE_SHIFT
++ #define PAGE_SHIFT 12
++ #define PAGE_SIZE (1UL << PAGE_SHIFT)
++#endif
++ static Thread* _sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
++#endif // !AMD64
++
++public:
++
++#ifndef AMD64
++ static Thread** sp_map_addr() { return _sp_map; }
++#endif // !AMD64
++
++ static Thread* thread() {
++#ifdef AMD64
++ return (Thread*) os::thread_local_storage_at(thread_index());
++#else
++ uintptr_t sp;
++ __asm__ volatile ("movl %%esp, %0" : "=r" (sp));
++ return _sp_map[sp >> PAGE_SHIFT];
++#endif // AMD64
++ }
++
++#endif // OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (c) 2000, 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_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
++#define OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
++
++// These are the OS and CPU-specific fields, types and integer
++// constants required by the Serviceability Agent. This file is
++// referenced by vmStructs.cpp.
++
++#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
++ \
++ /******************************/ \
++ /* Threads (NOTE: incomplete) */ \
++ /******************************/ \
++ nonstatic_field(OSThread, _thread_id, pthread_t) \
++ nonstatic_field(OSThread, _pthread_id, pthread_t) \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++
++#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
++ \
++ /**********************/ \
++ /* Posix Thread IDs */ \
++ /**********************/ \
++ \
++ declare_integer_type(pid_t) \
++ declare_unsigned_integer_type(pthread_t) \
++ \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
++ \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
++ \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/vm_version_bsd_x86.cpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/vm_version_bsd_x86.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/vm_version_bsd_x86.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/vm_version_bsd_x86.cpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,27 @@
++/*
++ * 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 "precompiled.hpp"
++#include "runtime/os.hpp"
++#include "vm_version_x86.hpp"
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2009 Red Hat, Inc.
++ * 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 "precompiled.hpp"
++#include "asm/assembler.hpp"
++#include "assembler_zero.inline.hpp"
++#include "runtime/os.hpp"
++#include "runtime/threadLocalStorage.hpp"
++
++// This file is intentionally empty
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,323 @@
++/*
++ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2011 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
++#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
++
++#include "orderAccess_bsd_zero.inline.hpp"
++#include "runtime/atomic.hpp"
++#include "runtime/os.hpp"
++#include "vm_version_zero.hpp"
++
++// Implementation of class atomic
++
++#ifdef M68K
++
++/*
++ * __m68k_cmpxchg
++ *
++ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
++ * Returns newval on success and oldval if no exchange happened.
++ * This implementation is processor specific and works on
++ * 68020 68030 68040 and 68060.
++ *
++ * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
++ * instruction.
++ * Using a kernelhelper would be better for arch complete implementation.
++ *
++ */
++
++static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
++ int ret;
++ __asm __volatile ("cas%.l %0,%2,%1"
++ : "=d" (ret), "+m" (*(ptr))
++ : "d" (newval), "0" (oldval));
++ return ret;
++}
++
++/* Perform an atomic compare and swap: if the current value of `*PTR'
++ is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
++ `*PTR' before the operation.*/
++static inline int m68k_compare_and_swap(volatile int *ptr,
++ int oldval,
++ int newval) {
++ for (;;) {
++ int prev = *ptr;
++ if (prev != oldval)
++ return prev;
++
++ if (__m68k_cmpxchg (prev, newval, ptr) == newval)
++ // Success.
++ return prev;
++
++ // We failed even though prev == oldval. Try again.
++ }
++}
++
++/* Atomically add an int to memory. */
++static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) {
++ for (;;) {
++ // Loop until success.
++
++ int prev = *ptr;
++
++ if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
++ return prev + add_value;
++ }
++}
++
++/* Atomically write VALUE into `*PTR' and returns the previous
++ contents of `*PTR'. */
++static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) {
++ for (;;) {
++ // Loop until success.
++ int prev = *ptr;
++
++ if (__m68k_cmpxchg (prev, newval, ptr) == prev)
++ return prev;
++ }
++}
++#endif // M68K
++
++#ifdef ARM
++
++/*
++ * __kernel_cmpxchg
++ *
++ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
++ * Return zero if *ptr was changed or non-zero if no exchange happened.
++ * The C flag is also set if *ptr was changed to allow for assembly
++ * optimization in the calling code.
++ *
++ */
++
++typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
++#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
++
++
++
++/* Perform an atomic compare and swap: if the current value of `*PTR'
++ is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
++ `*PTR' before the operation.*/
++static inline int arm_compare_and_swap(volatile int *ptr,
++ int oldval,
++ int newval) {
++ for (;;) {
++ int prev = *ptr;
++ if (prev != oldval)
++ return prev;
++
++ if (__kernel_cmpxchg (prev, newval, ptr) == 0)
++ // Success.
++ return prev;
++
++ // We failed even though prev == oldval. Try again.
++ }
++}
++
++/* Atomically add an int to memory. */
++static inline int arm_add_and_fetch(volatile int *ptr, int add_value) {
++ for (;;) {
++ // Loop until a __kernel_cmpxchg succeeds.
++
++ int prev = *ptr;
++
++ if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0)
++ return prev + add_value;
++ }
++}
++
++/* Atomically write VALUE into `*PTR' and returns the previous
++ contents of `*PTR'. */
++static inline int arm_lock_test_and_set(volatile int *ptr, int newval) {
++ for (;;) {
++ // Loop until a __kernel_cmpxchg succeeds.
++ int prev = *ptr;
++
++ if (__kernel_cmpxchg (prev, newval, ptr) == 0)
++ return prev;
++ }
++}
++#endif // ARM
++
++inline void Atomic::store(jint store_value, volatile jint* dest) {
++#if !defined(ARM) && !defined(M68K)
++ __sync_synchronize();
++#endif
++ *dest = store_value;
++}
++
++inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) {
++#if !defined(ARM) && !defined(M68K)
++ __sync_synchronize();
++#endif
++ *dest = store_value;
++}
++
++inline jint Atomic::add(jint add_value, volatile jint* dest) {
++#ifdef ARM
++ return arm_add_and_fetch(dest, add_value);
++#else
++#ifdef M68K
++ return m68k_add_and_fetch(dest, add_value);
++#else
++ return __sync_add_and_fetch(dest, add_value);
++#endif // M68K
++#endif // ARM
++}
++
++inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
++#ifdef ARM
++ return arm_add_and_fetch(dest, add_value);
++#else
++#ifdef M68K
++ return m68k_add_and_fetch(dest, add_value);
++#else
++ return __sync_add_and_fetch(dest, add_value);
++#endif // M68K
++#endif // ARM
++}
++
++inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
++ return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
++}
++
++inline void Atomic::inc(volatile jint* dest) {
++ add(1, dest);
++}
++
++inline void Atomic::inc_ptr(volatile intptr_t* dest) {
++ add_ptr(1, dest);
++}
++
++inline void Atomic::inc_ptr(volatile void* dest) {
++ add_ptr(1, dest);
++}
++
++inline void Atomic::dec(volatile jint* dest) {
++ add(-1, dest);
++}
++
++inline void Atomic::dec_ptr(volatile intptr_t* dest) {
++ add_ptr(-1, dest);
++}
++
++inline void Atomic::dec_ptr(volatile void* dest) {
++ add_ptr(-1, dest);
++}
++
++inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) {
++#ifdef ARM
++ return arm_lock_test_and_set(dest, exchange_value);
++#else
++#ifdef M68K
++ return m68k_lock_test_and_set(dest, exchange_value);
++#else
++ // __sync_lock_test_and_set is a bizarrely named atomic exchange
++ // operation. Note that some platforms only support this with the
++ // limitation that the only valid value to store is the immediate
++ // constant 1. There is a test for this in JNI_CreateJavaVM().
++ return __sync_lock_test_and_set (dest, exchange_value);
++#endif // M68K
++#endif // ARM
++}
++
++inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value,
++ volatile intptr_t* dest) {
++#ifdef ARM
++ return arm_lock_test_and_set(dest, exchange_value);
++#else
++#ifdef M68K
++ return m68k_lock_test_and_set(dest, exchange_value);
++#else
++ return __sync_lock_test_and_set (dest, exchange_value);
++#endif // M68K
++#endif // ARM
++}
++
++inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
++ return (void *) xchg_ptr((intptr_t) exchange_value,
++ (volatile intptr_t*) dest);
++}
++
++inline jint Atomic::cmpxchg(jint exchange_value,
++ volatile jint* dest,
++ jint compare_value) {
++#ifdef ARM
++ return arm_compare_and_swap(dest, compare_value, exchange_value);
++#else
++#ifdef M68K
++ return m68k_compare_and_swap(dest, compare_value, exchange_value);
++#else
++ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
++#endif // M68K
++#endif // ARM
++}
++
++inline jlong Atomic::cmpxchg(jlong exchange_value,
++ volatile jlong* dest,
++ jlong compare_value) {
++
++ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
++}
++
++inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value,
++ volatile intptr_t* dest,
++ intptr_t compare_value) {
++#ifdef ARM
++ return arm_compare_and_swap(dest, compare_value, exchange_value);
++#else
++#ifdef M68K
++ return m68k_compare_and_swap(dest, compare_value, exchange_value);
++#else
++ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
++#endif // M68K
++#endif // ARM
++}
++
++inline void* Atomic::cmpxchg_ptr(void* exchange_value,
++ volatile void* dest,
++ void* compare_value) {
++
++ return (void *) cmpxchg_ptr((intptr_t) exchange_value,
++ (volatile intptr_t*) dest,
++ (intptr_t) compare_value);
++}
++
++inline jlong Atomic::load(volatile jlong* src) {
++ volatile jlong dest;
++ os::atomic_copy64(src, &dest);
++ return dest;
++}
++
++inline void Atomic::store(jlong store_value, jlong* dest) {
++ os::atomic_copy64((volatile jlong*)&store_value, (volatile jlong*)dest);
++}
++
++inline void Atomic::store(jlong store_value, volatile jlong* dest) {
++ os::atomic_copy64((volatile jlong*)&store_value, dest);
++}
++
++#endif // OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,67 @@
++/*
++ * 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_CPU_BSD_ZERO_VM_BYTES_BSD_ZERO_INLINE_HPP
++#define OS_CPU_BSD_ZERO_VM_BYTES_BSD_ZERO_INLINE_HPP
++
++// Efficient swapping of data bytes from Java byte
++// ordering to native byte ordering and vice versa.
++
++#ifdef __APPLE__
++#include <libkern/OSByteOrder.h>
++#else
++# include <sys/endian.h>
++#endif
++
++#if defined(__APPLE__)
++# define bswap_16(x) OSSwapInt16(x)
++# define bswap_32(x) OSSwapInt32(x)
++# define bswap_64(x) OSSwapInt64(x)
++#elif defined(__OpenBSD__)
++# define bswap_16(x) swap16(x)
++# define bswap_32(x) swap32(x)
++# define bswap_64(x) swap64(x)
++#elif defined(__NetBSD__)
++# define bswap_16(x) bswap16(x)
++# define bswap_32(x) bswap32(x)
++# define bswap_64(x) bswap64(x)
++#else
++# define bswap_16(x) __bswap16(x)
++# define bswap_32(x) __bswap32(x)
++# define bswap_64(x) __bswap64(x)
++#endif
++
++inline u2 Bytes::swap_u2(u2 x) {
++ return bswap_16(x);
++}
++
++inline u4 Bytes::swap_u4(u4 x) {
++ return bswap_32(x);
++}
++
++inline u8 Bytes::swap_u8(u8 x) {
++ return bswap_64(x);
++}
++
++#endif // OS_CPU_BSD_ZERO_VM_BYTES_BSD_ZERO_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2010 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
++#define OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
++
++//
++// Set the default values for platform dependent flags used by the
++// runtime system. See globals.hpp for details of what they do.
++//
++
++define_pd_global(bool, DontYieldALot, false);
++define_pd_global(intx, ThreadStackSize, 1536);
++#ifdef _LP64
++define_pd_global(intx, VMThreadStackSize, 1024);
++#else
++define_pd_global(intx, VMThreadStackSize, 512);
++#endif // _LP64
++define_pd_global(intx, CompilerThreadStackSize, 0);
++define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
++
++define_pd_global(bool, UseVectoredExceptions, false);
++// Only used on 64 bit platforms
++define_pd_global(uintx, HeapBaseMinAddress, 2*G);
++
++#endif // OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,176 @@
++/*
++ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2009 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_ORDERACCESS_BSD_ZERO_INLINE_HPP
++#define OS_CPU_BSD_ZERO_VM_ORDERACCESS_BSD_ZERO_INLINE_HPP
++
++#include "runtime/orderAccess.hpp"
++#include "vm_version_zero.hpp"
++
++#ifdef ARM
++
++/*
++ * ARM Kernel helper for memory barrier.
++ * Using __asm __volatile ("":::"memory") does not work reliable on ARM
++ * and gcc __sync_synchronize(); implementation does not use the kernel
++ * helper for all gcc versions so it is unreliable to use as well.
++ */
++typedef void (__kernel_dmb_t) (void);
++#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
++
++#define FULL_MEM_BARRIER __kernel_dmb()
++#define READ_MEM_BARRIER __kernel_dmb()
++#define WRITE_MEM_BARRIER __kernel_dmb()
++
++#else // ARM
++
++#define FULL_MEM_BARRIER __sync_synchronize()
++
++#ifdef PPC
++
++#ifdef __NO_LWSYNC__
++#define READ_MEM_BARRIER __asm __volatile ("sync":::"memory")
++#define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
++#else
++#define READ_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
++#define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
++#endif
++
++#else // PPC
++
++#define READ_MEM_BARRIER __asm __volatile ("":::"memory")
++#define WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
++
++#endif // PPC
++
++#endif // ARM
++
++
++inline void OrderAccess::loadload() { acquire(); }
++inline void OrderAccess::storestore() { release(); }
++inline void OrderAccess::loadstore() { acquire(); }
++inline void OrderAccess::storeload() { fence(); }
++
++inline void OrderAccess::acquire() {
++ READ_MEM_BARRIER;
++}
++
++inline void OrderAccess::release() {
++ WRITE_MEM_BARRIER;
++}
++
++inline void OrderAccess::fence() {
++ FULL_MEM_BARRIER;
++}
++
++inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { jbyte data = *p; acquire(); return data; }
++inline jshort OrderAccess::load_acquire(volatile jshort* p) { jshort data = *p; acquire(); return data; }
++inline jint OrderAccess::load_acquire(volatile jint* p) { jint data = *p; acquire(); return data; }
++inline jlong OrderAccess::load_acquire(volatile jlong* p) {
++ jlong tmp;
++ os::atomic_copy64(p, &tmp);
++ acquire();
++ return tmp;
++}
++inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { jubyte data = *p; acquire(); return data; }
++inline jushort OrderAccess::load_acquire(volatile jushort* p) { jushort data = *p; acquire(); return data; }
++inline juint OrderAccess::load_acquire(volatile juint* p) { juint data = *p; acquire(); return data; }
++inline julong OrderAccess::load_acquire(volatile julong* p) {
++ julong tmp;
++ os::atomic_copy64(p, &tmp);
++ acquire();
++ return tmp;
++}
++inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { jfloat data = *p; acquire(); return data; }
++inline jdouble OrderAccess::load_acquire(volatile jdouble* p) {
++ jdouble tmp;
++ os::atomic_copy64(p, &tmp);
++ acquire();
++ return tmp;
++}
++
++inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) {
++ intptr_t data = *p;
++ acquire();
++ return data;
++}
++inline void* OrderAccess::load_ptr_acquire(volatile void* p) {
++ void *data = *(void* volatile *)p;
++ acquire();
++ return data;
++}
++inline void* OrderAccess::load_ptr_acquire(const volatile void* p) {
++ void *data = *(void* const volatile *)p;
++ acquire();
++ return data;
++}
++
++inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile jshort* p, jshort v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile jint* p, jint v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile jlong* p, jlong v)
++{ release(); os::atomic_copy64(&v, p); }
++inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile jushort* p, jushort v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile juint* p, juint v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile julong* p, julong v)
++{ release(); os::atomic_copy64(&v, p); }
++inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { release(); *p = v; }
++inline void OrderAccess::release_store(volatile jdouble* p, jdouble v)
++{ release(); os::atomic_copy64(&v, p); }
++
++inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { release(); *p = v; }
++inline void OrderAccess::release_store_ptr(volatile void* p, void* v)
++{ release(); *(void* volatile *)p = v; }
++
++inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(jlong* p, jlong v) { os::atomic_copy64(&v, p); fence(); }
++inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(julong* p, julong v) { os::atomic_copy64(&v, p); fence(); }
++inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); }
++inline void OrderAccess::store_fence(jdouble* p, jdouble v) { os::atomic_copy64(&v, p); fence(); }
++
++inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); }
++inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); }
++
++inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { release_store(p, v); fence(); }
++inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); }
++
++inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); }
++inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); }
++
++#endif // OS_CPU_BSD_ZERO_VM_ORDERACCESS_BSD_ZERO_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,558 @@
++/*
++ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
++ * 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.
++ *
++ */
++
++#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
++#include <pthread.h>
++# include <pthread_np.h> /* For pthread_attr_get_np */
++#endif
++
++// no precompiled headers
++#include "assembler_zero.inline.hpp"
++#include "classfile/classLoader.hpp"
++#include "classfile/systemDictionary.hpp"
++#include "classfile/vmSymbols.hpp"
++#include "code/icBuffer.hpp"
++#include "code/vtableStubs.hpp"
++#include "interpreter/interpreter.hpp"
++#include "jvm_bsd.h"
++#include "memory/allocation.inline.hpp"
++#include "mutex_bsd.inline.hpp"
++#include "nativeInst_zero.hpp"
++#include "os_share_bsd.hpp"
++#include "prims/jniFastGetField.hpp"
++#include "prims/jvm.h"
++#include "prims/jvm_misc.hpp"
++#include "runtime/arguments.hpp"
++#include "runtime/extendedPC.hpp"
++#include "runtime/frame.inline.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/java.hpp"
++#include "runtime/javaCalls.hpp"
++#include "runtime/mutexLocker.hpp"
++#include "runtime/osThread.hpp"
++#include "runtime/sharedRuntime.hpp"
++#include "runtime/stubRoutines.hpp"
++#include "runtime/timer.hpp"
++#include "thread_bsd.inline.hpp"
++#include "utilities/events.hpp"
++#include "utilities/vmError.hpp"
++#ifdef COMPILER1
++#include "c1/c1_Runtime1.hpp"
++#endif
++#ifdef COMPILER2
++#include "opto/runtime.hpp"
++#endif
++
++address os::current_stack_pointer() {
++ address dummy = (address) &dummy;
++ return dummy;
++}
++
++frame os::get_sender_for_C_frame(frame* fr) {
++ ShouldNotCallThis();
++}
++
++frame os::current_frame() {
++ // The only thing that calls this is the stack printing code in
++ // VMError::report:
++ // - Step 110 (printing stack bounds) uses the sp in the frame
++ // to determine the amount of free space on the stack. We
++ // set the sp to a close approximation of the real value in
++ // order to allow this step to complete.
++ // - Step 120 (printing native stack) tries to walk the stack.
++ // The frame we create has a NULL pc, which is ignored as an
++ // invalid frame.
++ frame dummy = frame();
++ dummy.set_sp((intptr_t *) current_stack_pointer());
++ return dummy;
++}
++
++char* os::non_memory_address_word() {
++ // Must never look like an address returned by reserve_memory,
++ // even in its subfields (as defined by the CPU immediate fields,
++ // if the CPU splits constants across multiple instructions).
++#ifdef SPARC
++ // On SPARC, 0 != %hi(any real address), because there is no
++ // allocation in the first 1Kb of the virtual address space.
++ return (char *) 0;
++#else
++ // This is the value for x86; works pretty well for PPC too.
++ return (char *) -1;
++#endif // SPARC
++}
++
++void os::initialize_thread() {
++ // Nothing to do.
++}
++
++address os::Bsd::ucontext_get_pc(ucontext_t* uc) {
++ ShouldNotCallThis();
++}
++
++ExtendedPC os::fetch_frame_from_context(void* ucVoid,
++ intptr_t** ret_sp,
++ intptr_t** ret_fp) {
++ ShouldNotCallThis();
++}
++
++frame os::fetch_frame_from_context(void* ucVoid) {
++ ShouldNotCallThis();
++}
++
++extern "C" JNIEXPORT int
++JVM_handle_bsd_signal(int sig,
++ siginfo_t* info,
++ void* ucVoid,
++ int abort_if_unrecognized) {
++ ucontext_t* uc = (ucontext_t*) ucVoid;
++
++ Thread* t = ThreadLocalStorage::get_thread_slow();
++
++ SignalHandlerMark shm(t);
++
++ // Note: it's not uncommon that JNI code uses signal/sigset to
++ // install then restore certain signal handler (e.g. to temporarily
++ // block SIGPIPE, or have a SIGILL handler when detecting CPU
++ // type). When that happens, JVM_handle_bsd_signal() might be
++ // invoked with junk info/ucVoid. To avoid unnecessary crash when
++ // libjsig is not preloaded, try handle signals that do not require
++ // siginfo/ucontext first.
++
++ if (sig == SIGPIPE || sig == SIGXFSZ) {
++ // allow chained handler to go first
++ if (os::Bsd::chained_handler(sig, info, ucVoid)) {
++ return true;
++ } else {
++ if (PrintMiscellaneous && (WizardMode || Verbose)) {
++ char buf[64];
++ warning("Ignoring %s - see bugs 4229104 or 646499219",
++ os::exception_name(sig, buf, sizeof(buf)));
++ }
++ return true;
++ }
++ }
++
++ JavaThread* thread = NULL;
++ VMThread* vmthread = NULL;
++ if (os::Bsd::signal_handlers_are_installed) {
++ if (t != NULL ){
++ if(t->is_Java_thread()) {
++ thread = (JavaThread*)t;
++ }
++ else if(t->is_VM_thread()){
++ vmthread = (VMThread *)t;
++ }
++ }
++ }
++
++ if (info != NULL && thread != NULL) {
++ // Handle ALL stack overflow variations here
++ if (sig == SIGSEGV) {
++ address addr = (address) info->si_addr;
++
++ // check if fault address is within thread stack
++ if (addr < thread->stack_base() &&
++ addr >= thread->stack_base() - thread->stack_size()) {
++ // stack overflow
++ if (thread->in_stack_yellow_zone(addr)) {
++ thread->disable_stack_yellow_zone();
++ ShouldNotCallThis();
++ }
++ else if (thread->in_stack_red_zone(addr)) {
++ thread->disable_stack_red_zone();
++ ShouldNotCallThis();
++ }
++#ifndef _ALLBSD_SOURCE
++ else {
++ // Accessing stack address below sp may cause SEGV if
++ // current thread has MAP_GROWSDOWN stack. This should
++ // only happen when current thread was created by user
++ // code with MAP_GROWSDOWN flag and then attached to VM.
++ // See notes in os_bsd.cpp.
++ if (thread->osthread()->expanding_stack() == 0) {
++ thread->osthread()->set_expanding_stack();
++ if (os::Bsd::manually_expand_stack(thread, addr)) {
++ thread->osthread()->clear_expanding_stack();
++ return true;
++ }
++ thread->osthread()->clear_expanding_stack();
++ }
++ else {
++ fatal("recursive segv. expanding stack.");
++ }
++ }
++#endif
++ }
++ }
++
++ /*if (thread->thread_state() == _thread_in_Java) {
++ ShouldNotCallThis();
++ }
++ else*/ if (thread->thread_state() == _thread_in_vm &&
++ sig == SIGBUS && thread->doing_unsafe_access()) {
++ ShouldNotCallThis();
++ }
++
++ // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC
++ // kicks in and the heap gets shrunk before the field access.
++ /*if (sig == SIGSEGV || sig == SIGBUS) {
++ address addr = JNI_FastGetField::find_slowcase_pc(pc);
++ if (addr != (address)-1) {
++ stub = addr;
++ }
++ }*/
++
++ // Check to see if we caught the safepoint code in the process
++ // 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 &&
++ os::is_memory_serialize_page(thread, (address) info->si_addr)) {
++ // Block current thread until permission is restored.
++ os::block_on_serialize_page_trap();
++ return true;
++ }
++ }
++
++ // signal-chaining
++ if (os::Bsd::chained_handler(sig, info, ucVoid)) {
++ return true;
++ }
++
++ if (!abort_if_unrecognized) {
++ // caller wants another chance, so give it to him
++ return false;
++ }
++
++#ifndef PRODUCT
++ if (sig == SIGSEGV) {
++ fatal("\n#"
++ "\n# /--------------------\\"
++ "\n# | segmentation fault |"
++ "\n# \\---\\ /--------------/"
++ "\n# /"
++ "\n# [-] |\\_/| "
++ "\n# (+)=C |o o|__ "
++ "\n# | | =-*-=__\\ "
++ "\n# OOO c_c_(___)");
++ }
++#endif // !PRODUCT
++
++ const char *fmt = "caught unhandled signal %d";
++ char buf[64];
++
++ sprintf(buf, fmt, sig);
++ fatal(buf);
++}
++
++void os::Bsd::init_thread_fpu_state(void) {
++ // Nothing to do
++}
++
++#ifndef _ALLBSD_SOURCE
++int os::Bsd::get_fpu_control_word() {
++ ShouldNotCallThis();
++}
++
++void os::Bsd::set_fpu_control_word(int fpu) {
++ ShouldNotCallThis();
++}
++#endif
++
++bool os::is_allocatable(size_t bytes) {
++#ifdef _LP64
++ return true;
++#else
++ if (bytes < 2 * G) {
++ return true;
++ }
++
++ char* addr = reserve_memory(bytes, NULL);
++
++ if (addr != NULL) {
++ release_memory(addr, bytes);
++ }
++
++ return addr != NULL;
++#endif // _LP64
++}
++
++///////////////////////////////////////////////////////////////////////////////
++// thread stack
++
++size_t os::Bsd::min_stack_allowed = 64 * K;
++
++bool os::Bsd::supports_variable_stack_size() {
++ return true;
++}
++
++size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
++#ifdef _LP64
++ size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
++#else
++ size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
++#endif // _LP64
++ return s;
++}
++
++size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
++ // Only enable glibc guard pages for non-Java threads
++ // (Java threads have HotSpot guard pages)
++ return (thr_type == java_thread ? 0 : page_size());
++}
++
++static void current_stack_region(address *bottom, size_t *size) {
++ address stack_bottom;
++ address stack_top;
++ size_t stack_bytes;
++
++#ifdef __APPLE__
++ pthread_t self = pthread_self();
++ stack_top = (address) pthread_get_stackaddr_np(self);
++ stack_bytes = pthread_get_stacksize_np(self);
++ stack_bottom = stack_top - stack_bytes;
++#elif defined(__OpenBSD__)
++ stack_t ss;
++ int rslt = pthread_stackseg_np(pthread_self(), &ss);
++
++ if (rslt != 0)
++ fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt));
++
++ stack_top = (address) ss.ss_sp;
++ stack_bytes = ss.ss_size;
++ stack_bottom = stack_top - stack_bytes;
++#elif defined(_ALLBSD_SOURCE)
++ pthread_attr_t attr;
++
++ int rslt = pthread_attr_init(&attr);
++
++ // 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));
++
++ rslt = pthread_attr_get_np(pthread_self(), &attr);
++
++ if (rslt != 0)
++ fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt));
++
++ if (pthread_attr_getstackaddr(&attr, (void **) &stack_bottom) != 0 ||
++ pthread_attr_getstacksize(&attr, &stack_bytes) != 0) {
++ fatal("Can not locate current stack attributes!");
++ }
++
++ pthread_attr_destroy(&attr);
++
++ stack_top = stack_bottom + stack_bytes;
++#else /* Linux */
++ pthread_attr_t attr;
++ int res = pthread_getattr_np(pthread_self(), &attr);
++ if (res != 0) {
++ if (res == ENOMEM) {
++ vm_exit_out_of_memory(0, "pthread_getattr_np");
++ }
++ else {
++ fatal(err_msg("pthread_getattr_np failed with errno = %d", 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));
++ }
++ stack_top = stack_bottom + stack_bytes;
++
++ // The block of memory returned by pthread_attr_getstack() includes
++ // guard pages where present. We need to trim these off.
++ size_t page_bytes = os::Bsd::page_size();
++ assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
++
++ size_t guard_bytes;
++ res = pthread_attr_getguardsize(&attr, &guard_bytes);
++ if (res != 0) {
++ fatal(err_msg("pthread_attr_getguardsize failed with errno = %d", res));
++ }
++ int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes;
++ assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
++
++#ifdef IA64
++ // IA64 has two stacks sharing the same area of memory, a normal
++ // stack growing downwards and a register stack growing upwards.
++ // Guard pages, if present, are in the centre. This code splits
++ // the stack in two even without guard pages, though in theory
++ // there's nothing to stop us allocating more to the normal stack
++ // or more to the register stack if one or the other were found
++ // to grow faster.
++ int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes;
++ stack_bottom += (total_pages - guard_pages) / 2 * page_bytes;
++#endif // IA64
++
++ stack_bottom += guard_bytes;
++
++ pthread_attr_destroy(&attr);
++
++ // The initial thread has a growable stack, and the size reported
++ // by pthread_attr_getstack is the maximum size it could possibly
++ // be given what currently mapped. This can be huge, so we cap it.
++ if (os::Bsd::is_initial_thread()) {
++ stack_bytes = stack_top - stack_bottom;
++
++ if (stack_bytes > JavaThread::stack_size_at_create())
++ stack_bytes = JavaThread::stack_size_at_create();
++
++ stack_bottom = stack_top - stack_bytes;
++ }
++#endif
++
++ assert(os::current_stack_pointer() >= stack_bottom, "should do");
++ assert(os::current_stack_pointer() < stack_top, "should do");
++
++ *bottom = stack_bottom;
++ *size = stack_top - stack_bottom;
++}
++
++address os::current_stack_base() {
++ address bottom;
++ size_t size;
++ current_stack_region(&bottom, &size);
++ return bottom + size;
++}
++
++size_t os::current_stack_size() {
++ // stack size includes normal stack and HotSpot guard pages
++ address bottom;
++ size_t size;
++ current_stack_region(&bottom, &size);
++ return size;
++}
++
++/////////////////////////////////////////////////////////////////////////////
++// helper functions for fatal error handler
++
++void os::print_context(outputStream* st, void* context) {
++ ShouldNotCallThis();
++}
++
++void os::print_register_info(outputStream *st, void *context) {
++ ShouldNotCallThis();
++}
++
++/////////////////////////////////////////////////////////////////////////////
++// Stubs for things that would be in bsd_zero.s if it existed.
++// You probably want to disassemble these monkeys to check they're ok.
++
++extern "C" {
++ int SpinPause() {
++ }
++
++ int SafeFetch32(int *adr, int errValue) {
++ int value = errValue;
++ value = *adr;
++ return value;
++ }
++ intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
++ intptr_t value = errValue;
++ value = *adr;
++ return value;
++ }
++
++ void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
++ if (from > to) {
++ jshort *end = from + count;
++ while (from < end)
++ *(to++) = *(from++);
++ }
++ else if (from < to) {
++ jshort *end = from;
++ from += count - 1;
++ to += count - 1;
++ while (from >= end)
++ *(to--) = *(from--);
++ }
++ }
++ void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
++ if (from > to) {
++ jint *end = from + count;
++ while (from < end)
++ *(to++) = *(from++);
++ }
++ else if (from < to) {
++ jint *end = from;
++ from += count - 1;
++ to += count - 1;
++ while (from >= end)
++ *(to--) = *(from--);
++ }
++ }
++ void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
++ if (from > to) {
++ jlong *end = from + count;
++ while (from < end)
++ os::atomic_copy64(from++, to++);
++ }
++ else if (from < to) {
++ jlong *end = from;
++ from += count - 1;
++ to += count - 1;
++ while (from >= end)
++ os::atomic_copy64(from--, to--);
++ }
++ }
++
++ void _Copy_arrayof_conjoint_bytes(HeapWord* from,
++ HeapWord* to,
++ size_t count) {
++ memmove(to, from, count);
++ }
++ void _Copy_arrayof_conjoint_jshorts(HeapWord* from,
++ HeapWord* to,
++ size_t count) {
++ memmove(to, from, count * 2);
++ }
++ void _Copy_arrayof_conjoint_jints(HeapWord* from,
++ HeapWord* to,
++ size_t count) {
++ memmove(to, from, count * 4);
++ }
++ void _Copy_arrayof_conjoint_jlongs(HeapWord* from,
++ HeapWord* to,
++ size_t count) {
++ memmove(to, from, count * 8);
++ }
++};
++
++/////////////////////////////////////////////////////////////////////////////
++// Implementations of atomic operations not supported by processors.
++// -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html
++
++#ifndef _LP64
++extern "C" {
++ long long unsigned int __sync_val_compare_and_swap_8(
++ volatile void *ptr,
++ long long unsigned int oldval,
++ long long unsigned int newval) {
++ ShouldNotCallThis();
++ }
++};
++#endif // !_LP64
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2010 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_OS_BSD_ZERO_HPP
++#define OS_CPU_BSD_ZERO_VM_OS_BSD_ZERO_HPP
++
++ static void setup_fpu() {}
++
++ static bool is_allocatable(size_t bytes);
++
++ // Used to register dynamic code cache area with the OS
++ // Note: Currently only used in 64 bit Windows implementations
++ static bool register_code_area(char *low, char *high) { return true; }
++
++ // Atomically copy 64 bits of data
++ static void atomic_copy64(volatile void *src, volatile void *dst) {
++#if defined(PPC) && !defined(_LP64)
++ double tmp;
++ asm volatile ("lfd %0, 0(%1)\n"
++ "stfd %0, 0(%2)\n"
++ : "=f"(tmp)
++ : "b"(src), "b"(dst));
++#elif defined(S390) && !defined(_LP64)
++ double tmp;
++ asm volatile ("ld %0, 0(%1)\n"
++ "std %0, 0(%2)\n"
++ : "=r"(tmp)
++ : "a"(src), "a"(dst));
++#else
++ *(jlong *) dst = *(jlong *) src;
++#endif
++ }
++
++#endif // OS_CPU_BSD_ZERO_VM_OS_BSD_ZERO_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/prefetch_bsd_zero.inline.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/prefetch_bsd_zero.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/prefetch_bsd_zero.inline.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/prefetch_bsd_zero.inline.hpp 2013-04-08 01:49:33.610321941 +0100
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_PREFETCH_BSD_ZERO_INLINE_HPP
++#define OS_CPU_BSD_ZERO_VM_PREFETCH_BSD_ZERO_INLINE_HPP
++
++#include "runtime/prefetch.hpp"
++
++inline void Prefetch::read(void* loc, intx interval) {
++}
++
++inline void Prefetch::write(void* loc, intx interval) {
++}
++
++#endif // OS_CPU_BSD_ZERO_VM_PREFETCH_BSD_ZERO_INLINE_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2009, 2010 Red Hat, Inc.
++ * 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 "precompiled.hpp"
++#include "runtime/frame.inline.hpp"
++#include "thread_bsd.inline.hpp"
++
++void JavaThread::cache_global_variables() {
++ // nothing to do
++}
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_THREAD_BSD_ZERO_HPP
++#define OS_CPU_BSD_ZERO_VM_THREAD_BSD_ZERO_HPP
++
++ private:
++ ZeroStack _zero_stack;
++ ZeroFrame* _top_zero_frame;
++
++ void pd_initialize() {
++ _top_zero_frame = NULL;
++ }
++
++ public:
++ ZeroStack *zero_stack() {
++ return &_zero_stack;
++ }
++
++ public:
++ ZeroFrame *top_zero_frame() {
++ return _top_zero_frame;
++ }
++ void push_zero_frame(ZeroFrame *frame) {
++ *(ZeroFrame **) frame = _top_zero_frame;
++ _top_zero_frame = frame;
++ }
++ void pop_zero_frame() {
++ zero_stack()->set_sp((intptr_t *) _top_zero_frame + 1);
++ _top_zero_frame = *(ZeroFrame **) _top_zero_frame;
++ }
++
++ public:
++ static ByteSize zero_stack_offset() {
++ return byte_offset_of(JavaThread, _zero_stack);
++ }
++ static ByteSize top_zero_frame_offset() {
++ return byte_offset_of(JavaThread, _top_zero_frame);
++ }
++
++ public:
++ void record_base_of_stack_pointer() {
++ assert(top_zero_frame() == NULL, "junk on stack prior to Java call");
++ }
++ void set_base_of_stack_pointer(intptr_t* base_sp) {
++ assert(base_sp == NULL, "should be");
++ assert(top_zero_frame() == NULL, "junk on stack after Java call");
++ }
++
++ public:
++ void set_last_Java_frame() {
++ set_last_Java_frame(top_zero_frame(), zero_stack()->sp());
++ }
++ void reset_last_Java_frame() {
++ frame_anchor()->zap();
++ }
++ void set_last_Java_frame(ZeroFrame* fp, intptr_t* sp) {
++ frame_anchor()->set(sp, NULL, fp);
++ }
++
++ public:
++ ZeroFrame* last_Java_fp() {
++ return frame_anchor()->last_Java_fp();
++ }
++
++ private:
++ frame pd_last_frame() {
++ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
++ return frame(last_Java_fp(), last_Java_sp());
++ }
++
++ public:
++ static ByteSize last_Java_fp_offset() {
++ return byte_offset_of(JavaThread, _anchor) +
++ JavaFrameAnchor::last_Java_fp_offset();
++ }
++
++ public:
++ // Check for pending suspend requests and pending asynchronous
++ // exceptions. There are separate accessors for these, but
++ // _suspend_flags is volatile so using them would be unsafe.
++ bool has_special_condition_for_native_trans() {
++ return _suspend_flags != 0;
++ }
++
++ public:
++ bool pd_get_top_frame_for_signal_handler(frame* fr_addr,
++ void* ucontext,
++ bool isInJava) {
++ ShouldNotCallThis();
++ }
++
++ // These routines are only used on cpu architectures that
++ // have separate register stacks (Itanium).
++ static bool register_stack_overflow() { return false; }
++ static void enable_register_stack_guard() {}
++ static void disable_register_stack_guard() {}
++
++#endif // OS_CPU_BSD_ZERO_VM_THREAD_BSD_ZERO_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007 Red Hat, Inc.
++ * 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 "precompiled.hpp"
++#include "runtime/threadLocalStorage.hpp"
++#include "thread_bsd.inline.hpp"
++
++void ThreadLocalStorage::generate_code_for_get_thread() {
++ // nothing to do
++}
++
++void ThreadLocalStorage::pd_init() {
++ // nothing to do
++}
++
++void ThreadLocalStorage::pd_set_thread(Thread* thread) {
++ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
++}
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -0,0 +1,35 @@
++/*
++ * 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_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
++#define OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
++
++// Processor dependent parts of ThreadLocalStorage
++
++ public:
++ static Thread* thread() {
++ return (Thread*) os::thread_local_storage_at(thread_index());
++ }
++
++#endif // OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007 Red Hat, Inc.
++ * 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_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
++#define OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
++
++// These are the OS and CPU-specific fields, types and integer
++// constants required by the Serviceability Agent. This file is
++// referenced by vmStructs.cpp.
++
++#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++
++#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
++ /* This must be the last entry, and must be present */ \
++ last_entry()
++
++#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/vm_version_bsd_zero.cpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/vm_version_bsd_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/vm_version_bsd_zero.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/vm_version_bsd_zero.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2009 Red Hat, Inc.
++ * 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 "precompiled.hpp"
++#include "runtime/os.hpp"
++#include "vm_version_zero.hpp"
++
++// This file is intentionally empty
+diff -Nru openjdk.orig/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp openjdk/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp
+--- openjdk.orig/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -38,7 +38,6 @@
+ #else
+ define_pd_global(intx, VMThreadStackSize, 512);
+ #endif // _LP64
+-define_pd_global(intx, SurvivorRatio, 8);
+ define_pd_global(intx, CompilerThreadStackSize, 0);
+ define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/adlc/adlc.hpp openjdk/hotspot/src/share/vm/adlc/adlc.hpp
+--- openjdk.orig/hotspot/src/share/vm/adlc/adlc.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/adlc/adlc.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -67,9 +67,9 @@
+ #endif
+ #endif // _WIN32
+
+-#ifdef LINUX
++#if defined(LINUX) || defined(_ALLBSD_SOURCE)
+ #include <inttypes.h>
+-#endif // LINUX
++#endif // LINUX || _ALLBSD_SOURCE
+
+ // Macros
+ #define uint32 unsigned int
+diff -Nru openjdk.orig/hotspot/src/share/vm/c1/c1_globals.hpp openjdk/hotspot/src/share/vm/c1/c1_globals.hpp
+--- openjdk.orig/hotspot/src/share/vm/c1/c1_globals.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/c1/c1_globals.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -47,6 +47,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "c1_globals_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "c1_globals_bsd.hpp"
++#endif
+
+ //
+ // Defines all global flags used by the client compiler.
+diff -Nru openjdk.orig/hotspot/src/share/vm/classfile/classLoader.cpp openjdk/hotspot/src/share/vm/classfile/classLoader.cpp
+--- openjdk.orig/hotspot/src/share/vm/classfile/classLoader.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/classfile/classLoader.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -68,6 +68,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ // Entry points in zip.dll for loading zip/jar file entries
+diff -Nru openjdk.orig/hotspot/src/share/vm/classfile/javaClasses.cpp openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp
+--- openjdk.orig/hotspot/src/share/vm/classfile/javaClasses.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -59,6 +59,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \
+ klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum);
+@@ -1159,7 +1162,7 @@
+ }
+ nmethod* nm = method->code();
+ if (WizardMode && nm != NULL) {
+- sprintf(buf + (int)strlen(buf), "(nmethod " PTR_FORMAT ")", (intptr_t)nm);
++ sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
+ }
+ }
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/code/stubs.hpp openjdk/hotspot/src/share/vm/code/stubs.hpp
+--- openjdk.orig/hotspot/src/share/vm/code/stubs.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/code/stubs.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ // The classes in this file provide a simple framework for the
+ // management of little pieces of machine code - or stubs -
+diff -Nru openjdk.orig/hotspot/src/share/vm/compiler/disassembler.hpp openjdk/hotspot/src/share/vm/compiler/disassembler.hpp
+--- openjdk.orig/hotspot/src/share/vm/compiler/disassembler.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/compiler/disassembler.hpp 2013-04-08 01:49:33.614322005 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ class decode_env;
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+ elapsedTimer CMSAdaptiveSizePolicy::_concurrent_timer;
+ elapsedTimer CMSAdaptiveSizePolicy::_STW_timer;
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp 2013-04-08 01:49:33.614322005 +0100
+@@ -50,6 +50,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ //
+ // ConcurrentMarkSweepPolicy methods
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp 2013-04-08 01:49:33.618322069 +0100
+@@ -36,6 +36,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ class ConcurrentMarkSweepGeneration;
+ class CMSCollector;
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -33,6 +33,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #ifndef PRODUCT
+ Mutex* FreeBlockDictionary::par_lock() const {
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp openjdk/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -39,6 +39,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
+ bool consume,
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp openjdk/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap,
+ int max_covered_regions) :
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp openjdk/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ PtrQueue::PtrQueue(PtrQueueSet* qset, bool perm, bool active) :
+ _qset(qset), _buf(NULL), _index(0), _active(active),
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -38,6 +38,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ bool
+ ParMarkBitMap::initialize(MemRegion covered_region)
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ // PSVirtualSpace
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_interface/collectedHeap.cpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_interface/collectedHeap.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -39,6 +39,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ #ifdef ASSERT
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
+--- openjdk.orig/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp 2013-04-08 01:49:33.618322069 +0100
+@@ -43,6 +43,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Inline allocation implementations.
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp
+--- openjdk.orig/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp 2013-04-08 01:49:33.618322069 +0100
+@@ -56,6 +56,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // This file contains the platform-independent parts
+ // of the abstract interpreter and the abstract interpreter generator.
+diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
+--- openjdk.orig/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp 2013-04-08 01:49:33.618322069 +0100
+@@ -65,6 +65,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "orderAccess_linux_ppc.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "orderAccess_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "orderAccess_bsd_zero.inline.hpp"
++#endif
+
+
+ // no precompiled headers
+diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp
+--- openjdk.orig/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -92,7 +92,7 @@
+ // the incoming method. We could lose a line of trace output.
+ // This is acceptable in a debug-only feature.
+ st->cr();
+- st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
++ st->print("[%ld] ", (long) Thread::current()->osthread()->thread_id());
+ method->print_name(st);
+ st->cr();
+ _current_method = method();
+@@ -106,7 +106,7 @@
+ }
+ _code = code;
+ int bci = bcp - method->code_base();
+- st->print("[%d] ", (int) Thread::current()->osthread()->thread_id());
++ st->print("[%ld] ", (long) Thread::current()->osthread()->thread_id());
+ if (Verbose) {
+ st->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s",
+ BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code));
+diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
+--- openjdk.orig/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp 2013-04-08 01:49:33.622322133 +0100
+@@ -41,6 +41,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // The InterpreterRuntime is called by the interpreter for everything
+ // that cannot/should not be dealt with in assembly and needs C support.
+diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/linkResolver.cpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp
+--- openjdk.orig/hotspot/src/share/vm/interpreter/linkResolver.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -52,6 +52,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ //------------------------------------------------------------------------------------------------------------------------
+ // Implementation of FieldAccessInfo
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/allocation.cpp openjdk/hotspot/src/share/vm/memory/allocation.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/allocation.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/allocation.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -39,6 +39,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ void* CHeapObj::operator new(size_t size){
+ return (void *) AllocateHeap(size, "CHeapObj-new");
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/collectorPolicy.cpp openjdk/hotspot/src/share/vm/memory/collectorPolicy.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/collectorPolicy.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/collectorPolicy.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -47,6 +47,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
+ #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/defNewGeneration.cpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/defNewGeneration.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -48,6 +48,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ //
+ // DefNewGeneration functions.
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/gcLocker.hpp openjdk/hotspot/src/share/vm/memory/gcLocker.hpp
+--- openjdk.orig/hotspot/src/share/vm/memory/gcLocker.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/gcLocker.hpp 2013-04-08 01:49:33.622322133 +0100
+@@ -41,6 +41,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // The direct lock/unlock calls do not force a collection if an unlock
+ // decrements the count to zero. Avoid calling these if at all possible.
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/genMarkSweep.cpp openjdk/hotspot/src/share/vm/memory/genMarkSweep.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/genMarkSweep.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/genMarkSweep.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -55,6 +55,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
+ bool clear_all_softrefs) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/resourceArea.cpp openjdk/hotspot/src/share/vm/memory/resourceArea.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/resourceArea.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/resourceArea.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ //------------------------------ResourceMark-----------------------------------
+ debug_only(int ResourceArea::_warned;) // to suppress multiple warnings
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/resourceArea.hpp openjdk/hotspot/src/share/vm/memory/resourceArea.hpp
+--- openjdk.orig/hotspot/src/share/vm/memory/resourceArea.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/resourceArea.hpp 2013-04-08 01:49:33.622322133 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // The resource area holds temporary data structures in the VM.
+ // The actual allocation areas are thread local. Typical usage:
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/space.hpp openjdk/hotspot/src/share/vm/memory/space.hpp
+--- openjdk.orig/hotspot/src/share/vm/memory/space.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/space.hpp 2013-04-08 01:49:33.622322133 +0100
+@@ -44,6 +44,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ // A space is an abstraction for the "storage units" backing
+ // up the generation abstraction. It includes specific
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp 2013-04-08 01:49:33.622322133 +0100
+@@ -38,6 +38,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Thread-Local Edens support
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/memory/universe.cpp openjdk/hotspot/src/share/vm/memory/universe.cpp
+--- openjdk.orig/hotspot/src/share/vm/memory/universe.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/memory/universe.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -89,6 +89,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
+ #include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/constantPoolKlass.cpp openjdk/hotspot/src/share/vm/oops/constantPoolKlass.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/constantPoolKlass.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/constantPoolKlass.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -44,6 +44,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/parNew/parOopClosures.inline.hpp"
+ #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/constantPoolOop.cpp openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/constantPoolOop.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -1355,7 +1355,7 @@
+ }
+ case JVM_CONSTANT_Long: {
+ u8 val = Bytes::get_Java_u8(bytes);
+- printf("long "INT64_FORMAT, *(jlong *) &val);
++ printf("long "INT64_FORMAT, (int64_t) *(jlong *) &val);
+ ent_size = 8;
+ idx++; // Long takes two cpool slots
+ break;
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/instanceKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/instanceKlass.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -61,6 +61,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+ #include "gc_implementation/g1/g1OopClosures.inline.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/markOop.cpp openjdk/hotspot/src/share/vm/oops/markOop.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/markOop.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/markOop.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -33,6 +33,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ void markOopDesc::print_on(outputStream* st) const {
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/oop.cpp openjdk/hotspot/src/share/vm/oops/oop.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/oop.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/oop.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -36,6 +36,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ bool always_do_update_barrier = false;
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/oopsHierarchy.cpp openjdk/hotspot/src/share/vm/oops/oopsHierarchy.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/oopsHierarchy.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/oopsHierarchy.cpp 2013-04-08 01:49:33.626322198 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #ifdef CHECK_UNHANDLED_OOPS
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/typeArrayOop.hpp openjdk/hotspot/src/share/vm/oops/typeArrayOop.hpp
+--- openjdk.orig/hotspot/src/share/vm/oops/typeArrayOop.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/oops/typeArrayOop.hpp 2013-04-08 01:49:33.626322198 +0100
+@@ -51,6 +51,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "orderAccess_linux_ppc.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "orderAccess_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "orderAccess_bsd_zero.inline.hpp"
++#endif
+
+ // A typeArrayOop is an array containing basic types (non oop elements).
+ // It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs}
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/c2_globals.hpp openjdk/hotspot/src/share/vm/opto/c2_globals.hpp
+--- openjdk.orig/hotspot/src/share/vm/opto/c2_globals.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/opto/c2_globals.hpp 2013-04-08 01:49:33.626322198 +0100
+@@ -44,6 +44,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "c2_globals_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "c2_globals_bsd.hpp"
++#endif
+
+ //
+ // Defines all globals flags used by the server compiler.
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/forte.cpp openjdk/hotspot/src/share/vm/prims/forte.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/forte.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/forte.cpp 2013-04-08 01:49:33.630322263 +0100
+@@ -621,6 +621,11 @@
+ // Method to let libcollector know about a dynamically loaded function.
+ // Because it is weakly bound, the calls become NOP's when the library
+ // isn't present.
++#ifdef __APPLE__
++// XXXDARWIN: Link errors occur even when __attribute__((weak_import))
++// is added
++#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) (0)
++#else
+ void collector_func_load(char* name,
+ void* null_argument_1,
+ void* null_argument_2,
+@@ -631,6 +636,7 @@
+ #pragma weak collector_func_load
+ #define collector_func_load(x0,x1,x2,x3,x4,x5,x6) \
+ ( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),0 : 0 )
++#endif // __APPLE__
+ #endif // !_WINDOWS
+
+ } // end extern "C"
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jni.cpp openjdk/hotspot/src/share/vm/prims/jni.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/jni.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/jni.cpp 2013-04-08 01:49:33.630322263 +0100
+@@ -83,6 +83,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ static jint CurrentVersion = JNI_VERSION_1_6;
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jvm.cpp openjdk/hotspot/src/share/vm/prims/jvm.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/jvm.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/jvm.cpp 2013-04-08 01:49:33.630322263 +0100
+@@ -73,6 +73,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "jvm_windows.h"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "jvm_bsd.h"
++#endif
+
+ #include <errno.h>
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jvm.h openjdk/hotspot/src/share/vm/prims/jvm.h
+--- openjdk.orig/hotspot/src/share/vm/prims/jvm.h 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/jvm.h 2013-04-08 01:49:33.630322263 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "jvm_windows.h"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "jvm_bsd.h"
++#endif
+
+ #ifndef _JAVASOFT_JVM_H_
+ #define _JAVASOFT_JVM_H_
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jvmtiEnv.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/jvmtiEnv.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp 2013-04-08 01:49:33.630322263 +0100
+@@ -68,6 +68,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jvmtiImpl.cpp openjdk/hotspot/src/share/vm/prims/jvmtiImpl.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/jvmtiImpl.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/jvmtiImpl.cpp 2013-04-08 01:49:33.630322263 +0100
+@@ -54,6 +54,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ //
+ // class JvmtiAgentThread
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/nativeLookup.cpp openjdk/hotspot/src/share/vm/prims/nativeLookup.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/nativeLookup.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/prims/nativeLookup.cpp 2013-04-08 01:49:33.630322263 +0100
+@@ -49,6 +49,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ static void mangle_name_on(outputStream* st, Symbol* name, int begin, int end) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/arguments.cpp openjdk/hotspot/src/share/vm/runtime/arguments.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/arguments.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/arguments.cpp 2013-04-08 01:49:33.634322327 +0100
+@@ -46,6 +46,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
+ #endif
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/atomic.cpp openjdk/hotspot/src/share/vm/runtime/atomic.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/atomic.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/atomic.cpp 2013-04-08 01:49:33.634322327 +0100
+@@ -33,6 +33,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_linux_x86
+ # include "atomic_linux_x86.inline.hpp"
+ #endif
+@@ -57,6 +60,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "atomic_linux_ppc.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "atomic_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "atomic_bsd_zero.inline.hpp"
++#endif
+
+ jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
+ assert(sizeof(jbyte) == 1, "assumption.");
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/fprofiler.hpp openjdk/hotspot/src/share/vm/runtime/fprofiler.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/fprofiler.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/fprofiler.hpp 2013-04-08 01:49:33.634322327 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // a simple flat profiler for Java
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp openjdk/hotspot/src/share/vm/runtime/globals.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/globals.hpp 2013-04-08 01:49:33.634322327 +0100
+@@ -50,6 +50,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "globals_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "globals_bsd.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_linux_x86
+ # include "globals_linux_x86.hpp"
+ #endif
+@@ -74,6 +77,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "globals_linux_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "globals_bsd_x86.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "globals_bsd_zero.hpp"
++#endif
+ #ifdef COMPILER1
+ #ifdef TARGET_ARCH_x86
+ # include "c1_globals_x86.hpp"
+@@ -96,6 +105,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "c1_globals_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "c1_globals_bsd.hpp"
++#endif
+ #endif
+ #ifdef COMPILER2
+ #ifdef TARGET_ARCH_x86
+@@ -116,6 +128,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "c2_globals_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "c2_globals_bsd.hpp"
++#endif
+ #endif
+ #ifdef SHARK
+ #ifdef TARGET_ARCH_zero
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/handles.cpp openjdk/hotspot/src/share/vm/runtime/handles.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/handles.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/handles.cpp 2013-04-08 01:49:33.634322327 +0100
+@@ -38,6 +38,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #ifdef ASSERT
+ oop* HandleArea::allocate_handle(oop obj) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/handles.inline.hpp openjdk/hotspot/src/share/vm/runtime/handles.inline.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/handles.inline.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/handles.inline.hpp 2013-04-08 01:49:33.634322327 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // these inline functions are in a separate file to break an include cycle
+ // between Thread and Handle
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/interfaceSupport.hpp openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/interfaceSupport.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp 2013-04-08 01:49:33.634322327 +0100
+@@ -44,6 +44,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Wrapper for all entry points to the virtual machine.
+ // The HandleMarkCleaner is a faster version of HandleMark.
+@@ -115,6 +118,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "interfaceSupport_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "interfaceSupport_bsd.hpp"
++#endif
+
+ };
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/javaCalls.cpp openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/javaCalls.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -48,6 +48,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // -----------------------------------------------------
+ // Implementation of JavaCallWrapper
+@@ -557,4 +560,3 @@
+ sc.check_doing_return(true);
+ sc.iterate_returntype();
+ }
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/javaCalls.hpp openjdk/hotspot/src/share/vm/runtime/javaCalls.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/javaCalls.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/javaCalls.hpp 2013-04-08 01:49:33.638322390 +0100
+@@ -54,6 +54,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // A JavaCallWrapper is constructed before each JavaCall and destructed after the call.
+ // Its purpose is to allocate/deallocate a new handle block and to save/restore the last
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/java.cpp openjdk/hotspot/src/share/vm/runtime/java.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/java.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/java.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -85,6 +85,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
+ #include "gc_implementation/parallelScavenge/psScavenge.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp openjdk/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp 2013-04-08 01:49:33.638322390 +0100
+@@ -50,6 +50,13 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "orderAccess_linux_ppc.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "orderAccess_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "orderAccess_bsd_zero.inline.hpp"
++#endif
++
+ //
+ // An object for encapsulating the machine/os dependent part of a JavaThread frame state
+ //
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/jniHandles.cpp openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/jniHandles.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ JNIHandleBlock* JNIHandles::_global_handles = NULL;
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/memprofiler.cpp openjdk/hotspot/src/share/vm/runtime/memprofiler.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/memprofiler.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/memprofiler.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -46,6 +46,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #ifndef PRODUCT
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/mutex.cpp openjdk/hotspot/src/share/vm/runtime/mutex.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/mutex.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/mutex.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -39,6 +39,10 @@
+ # include "mutex_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "mutex_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
+ //
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/mutexLocker.cpp openjdk/hotspot/src/share/vm/runtime/mutexLocker.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/mutexLocker.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/mutexLocker.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -36,6 +36,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Mutexes used in the VM (see comment in mutexLocker.hpp):
+ //
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/mutexLocker.hpp openjdk/hotspot/src/share/vm/runtime/mutexLocker.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/mutexLocker.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/mutexLocker.hpp 2013-04-08 01:49:33.638322390 +0100
+@@ -36,6 +36,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ // Mutexes used in the VM.
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/objectMonitor.cpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/objectMonitor.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp 2013-04-08 01:49:33.638322390 +0100
+@@ -50,6 +50,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #if defined(__GNUC__) && !defined(IA64)
+ // Need to inhibit inlining for older versions of GCC to avoid build-time failures
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.cpp openjdk/hotspot/src/share/vm/runtime/os.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/os.cpp 2013-04-08 01:48:11.805006641 +0100
++++ openjdk/hotspot/src/share/vm/runtime/os.cpp 2013-04-08 01:49:33.642322455 +0100
+@@ -60,6 +60,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ # include <signal.h>
+
+@@ -116,7 +120,11 @@
+ assert(false, "Failed localtime_pd");
+ return NULL;
+ }
++#if defined(_ALLBSD_SOURCE)
++ const time_t zone = (time_t) time_struct.tm_gmtoff;
++#else
+ const time_t zone = timezone;
++#endif
+
+ // If daylight savings time is in effect,
+ // we are 1 hour East of our time zone
+@@ -384,6 +392,13 @@
+ if (_native_java_library == NULL) {
+ vm_exit_during_initialization("Unable to load native library", ebuf);
+ }
++
++#if defined(__OpenBSD__)
++ // Work-around OpenBSD's lack of $ORIGIN support by pre-loading libnet.so
++ // ignore errors
++ dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "net");
++ dll_load(buffer, ebuf, sizeof(ebuf));
++#endif
+ }
+ static jboolean onLoaded = JNI_FALSE;
+ if (onLoaded) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.hpp openjdk/hotspot/src/share/vm/runtime/os.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/os.hpp 2013-04-08 01:48:11.805006641 +0100
++++ openjdk/hotspot/src/share/vm/runtime/os.hpp 2013-04-08 01:49:33.642322455 +0100
+@@ -39,6 +39,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "jvm_windows.h"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "jvm_bsd.h"
++#endif
+
+ // os defines the interface to operating system; this includes traditional
+ // OS services (time, I/O) as well as other functionality with system-
+@@ -671,6 +674,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_linux_x86
+ # include "os_linux_x86.hpp"
+ #endif
+@@ -695,6 +701,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "os_linux_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "os_bsd_x86.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "os_bsd_zero.hpp"
++#endif
+
+
+ // debugging support (mostly used by debug.cpp but also fatal error handler)
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/osThread.hpp openjdk/hotspot/src/share/vm/runtime/osThread.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/osThread.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/osThread.hpp 2013-04-08 01:49:33.642322455 +0100
+@@ -109,6 +109,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "osThread_windows.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "osThread_bsd.hpp"
++#endif
+
+ };
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/safepoint.cpp openjdk/hotspot/src/share/vm/runtime/safepoint.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/safepoint.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/safepoint.cpp 2013-04-08 01:49:33.642322455 +0100
+@@ -79,6 +79,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
+ #include "gc_implementation/shared/concurrentGCThread.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/synchronizer.cpp openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/synchronizer.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp 2013-04-08 01:49:33.642322455 +0100
+@@ -51,6 +51,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #if defined(__GNUC__) && !defined(IA64)
+ // Need to inhibit inlining for older versions of GCC to avoid build-time failures
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/task.cpp openjdk/hotspot/src/share/vm/runtime/task.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/task.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/task.cpp 2013-04-08 01:49:33.642322455 +0100
+@@ -39,6 +39,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ int PeriodicTask::_num_tasks = 0;
+ PeriodicTask* PeriodicTask::_tasks[PeriodicTask::max_tasks];
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/thread.cpp openjdk/hotspot/src/share/vm/runtime/thread.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/thread.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/thread.cpp 2013-04-08 01:49:33.642322455 +0100
+@@ -89,6 +89,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
+ #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/thread.hpp openjdk/hotspot/src/share/vm/runtime/thread.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/thread.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/thread.hpp 2013-04-08 01:49:33.646322519 +0100
+@@ -1607,6 +1607,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "thread_linux_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "thread_bsd_x86.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "thread_bsd_zero.hpp"
++#endif
+
+
+ public:
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/threadLocalStorage.cpp openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/threadLocalStorage.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.cpp 2013-04-08 01:49:33.646322519 +0100
+@@ -36,6 +36,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // static member initialization
+ int ThreadLocalStorage::_thread_index = -1;
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/threadLocalStorage.hpp openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/threadLocalStorage.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.hpp 2013-04-08 01:49:33.646322519 +0100
+@@ -68,6 +68,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "threadLS_linux_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "threadLS_bsd_x86.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "threadLS_bsd_zero.hpp"
++#endif
+
+
+ public:
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/timer.cpp openjdk/hotspot/src/share/vm/runtime/timer.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/timer.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/timer.cpp 2013-04-08 01:49:33.646322519 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ void elapsedTimer::add(elapsedTimer t) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/virtualspace.cpp openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/virtualspace.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp 2013-04-08 01:49:33.646322519 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ // ReservedSpace
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/vm_operations.cpp openjdk/hotspot/src/share/vm/runtime/vm_operations.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/vm_operations.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/vm_operations.cpp 2013-04-08 01:49:33.646322519 +0100
+@@ -45,6 +45,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #define VM_OP_NAME_INITIALIZE(name) #name,
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/vmStructs.cpp openjdk/hotspot/src/share/vm/runtime/vmStructs.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/vmStructs.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/vmStructs.cpp 2013-04-08 01:49:33.646322519 +0100
+@@ -133,6 +133,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_linux_x86
+ # include "vmStructs_linux_x86.hpp"
+ #endif
+@@ -157,6 +160,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "vmStructs_linux_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "vmStructs_bsd_x86.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "vmStructs_bsd_zero.hpp"
++#endif
+ #ifndef SERIALGC
+ #include "gc_implementation/concurrentMarkSweep/cmsPermGen.hpp"
+ #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/vmThread.cpp openjdk/hotspot/src/share/vm/runtime/vmThread.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/vmThread.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/vmThread.cpp 2013-04-08 01:49:33.646322519 +0100
+@@ -46,6 +46,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
+ HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/vmThread.hpp openjdk/hotspot/src/share/vm/runtime/vmThread.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/vmThread.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/vmThread.hpp 2013-04-08 01:49:33.650322584 +0100
+@@ -36,6 +36,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ //
+ // Prioritized queue of VM operations.
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/vm_version.cpp openjdk/hotspot/src/share/vm/runtime/vm_version.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/vm_version.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/vm_version.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -167,7 +167,8 @@
+
+ #define OS LINUX_ONLY("linux") \
+ WINDOWS_ONLY("windows") \
+- SOLARIS_ONLY("solaris")
++ SOLARIS_ONLY("solaris") \
++ BSD_ONLY("bsd")
+
+ #ifdef ZERO
+ #define CPU ZERO_LIBARCH
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/accessFlags.cpp openjdk/hotspot/src/share/vm/utilities/accessFlags.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/accessFlags.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/accessFlags.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -34,6 +34,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ void AccessFlags::atomic_set_bits(jint bits) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/array.cpp openjdk/hotspot/src/share/vm/utilities/array.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/array.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/array.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -34,6 +34,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ #ifdef ASSERT
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/bitMap.cpp openjdk/hotspot/src/share/vm/utilities/bitMap.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/bitMap.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/bitMap.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+
+ BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/debug.cpp openjdk/hotspot/src/share/vm/utilities/debug.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/debug.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/debug.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -62,6 +62,10 @@
+ # include "os_windows.inline.hpp"
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #ifndef ASSERT
+ # ifdef _DEBUG
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/decoder.cpp openjdk/hotspot/src/share/vm/utilities/decoder.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/decoder.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/decoder.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -29,7 +29,7 @@
+ Decoder::decoder_status Decoder::_decoder_status = Decoder::no_error;
+ bool Decoder::_initialized = false;
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+ // Implementation of common functionalities among Solaris and Linux
+ #include "utilities/elfFile.hpp"
+@@ -101,4 +101,3 @@
+ }
+
+ #endif
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/decoder.hpp openjdk/hotspot/src/share/vm/utilities/decoder.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/decoder.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/decoder.hpp 2013-04-08 01:49:33.650322584 +0100
+@@ -38,6 +38,8 @@
+ typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
+ typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
+
++#elif defined(__APPLE__)
++
+ #else
+
+ class ElfFile;
+@@ -79,7 +81,7 @@
+
+ static decoder_status get_status() { return _decoder_status; };
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+ private:
+ static ElfFile* get_elf_file(const char* filepath);
+ #endif // _WINDOWS
+@@ -94,6 +96,7 @@
+ static bool _can_decode_in_vm;
+ static pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64;
+ static pfn_UndecorateSymbolName _pfnUndecorateSymbolName;
++#elif __APPLE__
+ #else
+ static ElfFile* _opened_elf_files;
+ #endif // _WINDOWS
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/elfFile.cpp openjdk/hotspot/src/share/vm/utilities/elfFile.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/elfFile.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/elfFile.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -24,7 +24,7 @@
+
+ #include "precompiled.hpp"
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+ #include <string.h>
+ #include <stdio.h>
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/elfFile.hpp openjdk/hotspot/src/share/vm/utilities/elfFile.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/elfFile.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/elfFile.hpp 2013-04-08 01:49:33.650322584 +0100
+@@ -25,9 +25,13 @@
+ #ifndef __ELF_FILE_HPP
+ #define __ELF_FILE_HPP
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
++#if defined(__OpenBSD__)
++#include <sys/exec_elf.h>
++#else
+ #include <elf.h>
++#endif
+ #include <stdio.h>
+
+ #ifdef _LP64
+@@ -41,7 +45,9 @@
+ typedef Elf64_Shdr Elf_Shdr;
+ typedef Elf64_Sym Elf_Sym;
+
++#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
+ #define ELF_ST_TYPE ELF64_ST_TYPE
++#endif
+
+ #else
+
+@@ -55,8 +61,10 @@
+ typedef Elf32_Shdr Elf_Shdr;
+ typedef Elf32_Sym Elf_Sym;
+
++#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
+ #define ELF_ST_TYPE ELF32_ST_TYPE
+ #endif
++#endif
+
+ #include "globalDefinitions.hpp"
+ #include "memory/allocation.hpp"
+@@ -137,4 +145,3 @@
+ #endif // _WINDOWS
+
+ #endif // __ELF_FILE_HPP
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/elfStringTable.cpp openjdk/hotspot/src/share/vm/utilities/elfStringTable.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/elfStringTable.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/elfStringTable.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -24,7 +24,7 @@
+
+ #include "precompiled.hpp"
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+ #include "memory/allocation.inline.hpp"
+ #include "runtime/os.hpp"
+@@ -87,4 +87,3 @@
+ }
+
+ #endif // _WINDOWS
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/elfStringTable.hpp openjdk/hotspot/src/share/vm/utilities/elfStringTable.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/elfStringTable.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/elfStringTable.hpp 2013-04-08 01:49:33.650322584 +0100
+@@ -25,7 +25,7 @@
+ #ifndef __ELF_STRING_TABLE_HPP
+ #define __ELF_STRING_TABLE_HPP
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+ #include "memory/allocation.hpp"
+ #include "utilities/decoder.hpp"
+@@ -79,4 +79,3 @@
+ #endif // _WINDOWS
+
+ #endif // __ELF_STRING_TABLE_HPP
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/elfSymbolTable.cpp openjdk/hotspot/src/share/vm/utilities/elfSymbolTable.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/elfSymbolTable.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/elfSymbolTable.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -24,7 +24,7 @@
+
+ #include "precompiled.hpp"
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+ #include "memory/allocation.inline.hpp"
+ #include "utilities/elfSymbolTable.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/elfSymbolTable.hpp openjdk/hotspot/src/share/vm/utilities/elfSymbolTable.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/elfSymbolTable.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/elfSymbolTable.hpp 2013-04-08 01:49:33.650322584 +0100
+@@ -25,7 +25,7 @@
+ #ifndef __ELF_SYMBOL_TABLE_HPP
+ #define __ELF_SYMBOL_TABLE_HPP
+
+-#ifndef _WINDOWS
++#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+
+ #include "memory/allocation.hpp"
+@@ -68,6 +68,3 @@
+ #endif // _WINDOWS
+
+ #endif // __ELF_SYMBOL_TABLE_HPP
+-
+-
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/events.cpp openjdk/hotspot/src/share/vm/utilities/events.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/events.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/events.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -38,6 +38,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ #ifndef PRODUCT
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/exceptions.cpp openjdk/hotspot/src/share/vm/utilities/exceptions.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/exceptions.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/exceptions.cpp 2013-04-08 01:49:33.650322584 +0100
+@@ -42,6 +42,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+
+ // Implementation of ThreadShadow
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -76,15 +76,28 @@
+ # include <sys/procfs.h>
+ # endif
+
+-#ifdef LINUX
++#if defined(LINUX) || defined(_ALLBSD_SOURCE)
+ #ifndef __STDC_LIMIT_MACROS
+ #define __STDC_LIMIT_MACROS
+ #endif // __STDC_LIMIT_MACROS
+ #include <inttypes.h>
+ #include <signal.h>
++#ifndef __OpenBSD__
+ #include <ucontext.h>
++#endif
++#ifdef __APPLE__
++ #include <AvailabilityMacros.h>
++ #if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4)
++ // Mac OS X 10.4 defines EFL_AC and EFL_ID,
++ // which conflict with hotspot variable names.
++ //
++ // This has been fixed in Mac OS X 10.5.
++ #undef EFL_AC
++ #undef EFL_ID
++ #endif
++#endif
+ #include <sys/time.h>
+-#endif // LINUX
++#endif // LINUX || _ALLBSD_SOURCE
+
+ // 4810578: varargs unsafe on 32-bit integer/64-bit pointer architectures
+ // When __cplusplus is defined, NULL is defined as 0 (32-bit constant) in
+@@ -120,7 +133,7 @@
+ // pointer is stored as integer value. On some platforms, sizeof(intptr_t) >
+ // sizeof(void*), so here we want something which is integer type, but has the
+ // same size as a pointer.
+-#ifdef LINUX
++#ifdef __GNUC__
+ #ifdef _LP64
+ #define NULL_WORD 0L
+ #else
+@@ -132,7 +145,7 @@
+ #define NULL_WORD NULL
+ #endif
+
+-#ifndef LINUX
++#if !defined(LINUX) && !defined(_ALLBSD_SOURCE)
+ // Compiler-specific primitive types
+ typedef unsigned short uint16_t;
+ #ifndef _UINT32_T
+@@ -152,7 +165,7 @@
+ // prior definition of intptr_t, and add "&& !defined(XXX)" above.
+ #endif // _SYS_INT_TYPES_H
+
+-#endif // !LINUX
++#endif // !LINUX && !_ALLBSD_SOURCE
+
+ // Additional Java basic types
+
+@@ -244,7 +257,9 @@
+ inline int g_isnan(float f) { return isnand(f); }
+ #endif
+ inline int g_isnan(double f) { return isnand(f); }
+-#elif LINUX
++#elif defined(__APPLE__)
++inline int g_isnan(double f) { return isnan(f); }
++#elif defined(LINUX) || defined(_ALLBSD_SOURCE)
+ inline int g_isnan(float f) { return isnanf(f); }
+ inline int g_isnan(double f) { return isnan(f); }
+ #else
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -25,6 +25,8 @@
+ #ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
+ #define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
+
++#define __STDC_FORMAT_MACROS
++
+ #ifdef TARGET_COMPILER_gcc
+ # include "utilities/globalDefinitions_gcc.hpp"
+ #endif
+@@ -1178,67 +1180,47 @@
+ }
+
+ // Printf-style formatters for fixed- and variable-width types as pointers and
+-// integers.
+-//
+-// Each compiler-specific definitions file (e.g., globalDefinitions_gcc.hpp)
+-// must define the macro FORMAT64_MODIFIER, which is the modifier for '%x' or
+-// '%d' formats to indicate a 64-bit quantity; commonly "l" (in LP64) or "ll"
+-// (in ILP32).
++// integers. These are derived from the definitions in inttypes.h. If the platform
++// doesn't provide appropriate definitions, they should be provided in
++// the compiler-specific definitions file (e.g., globalDefinitions_gcc.hpp)
+
+ #define BOOL_TO_STR(_b_) ((_b_) ? "true" : "false")
+
+ // Format 32-bit quantities.
+-#define INT32_FORMAT "%d"
+-#define UINT32_FORMAT "%u"
+-#define INT32_FORMAT_W(width) "%" #width "d"
+-#define UINT32_FORMAT_W(width) "%" #width "u"
++#define INT32_FORMAT "%" PRId32
++#define UINT32_FORMAT "%" PRIu32
++#define INT32_FORMAT_W(width) "%" #width PRId32
++#define UINT32_FORMAT_W(width) "%" #width PRIu32
+
+-#define PTR32_FORMAT "0x%08x"
++#define PTR32_FORMAT "0x%08" PRIx32
+
+ // Format 64-bit quantities.
+-#define INT64_FORMAT "%" FORMAT64_MODIFIER "d"
+-#define UINT64_FORMAT "%" FORMAT64_MODIFIER "u"
+-#define PTR64_FORMAT "0x%016" FORMAT64_MODIFIER "x"
++#define INT64_FORMAT "%" PRId64
++#define UINT64_FORMAT "%" PRIu64
++#define INT64_FORMAT_W(width) "%" #width PRId64
++#define UINT64_FORMAT_W(width) "%" #width PRIu64
+
+-#define INT64_FORMAT_W(width) "%" #width FORMAT64_MODIFIER "d"
+-#define UINT64_FORMAT_W(width) "%" #width FORMAT64_MODIFIER "u"
++#define PTR64_FORMAT "0x%016" PRIx64
+
+-// Format macros that allow the field width to be specified. The width must be
+-// a string literal (e.g., "8") or a macro that evaluates to one.
+-#ifdef _LP64
+-#define UINTX_FORMAT_W(width) UINT64_FORMAT_W(width)
+-#define SSIZE_FORMAT_W(width) INT64_FORMAT_W(width)
+-#define SIZE_FORMAT_W(width) UINT64_FORMAT_W(width)
+-#else
+-#define UINTX_FORMAT_W(width) UINT32_FORMAT_W(width)
+-#define SSIZE_FORMAT_W(width) INT32_FORMAT_W(width)
+-#define SIZE_FORMAT_W(width) UINT32_FORMAT_W(width)
+-#endif // _LP64
+-
+-// Format pointers and size_t (or size_t-like integer types) which change size
+-// between 32- and 64-bit. The pointer format theoretically should be "%p",
+-// however, it has different output on different platforms. On Windows, the data
+-// will be padded with zeros automatically. On Solaris, we can use "%016p" &
+-// "%08p" on 64 bit & 32 bit platforms to make the data padded with extra zeros.
+-// On Linux, "%016p" or "%08p" is not be allowed, at least on the latest GCC
+-// 4.3.2. So we have to use "%016x" or "%08x" to simulate the printing format.
+-// GCC 4.3.2, however requires the data to be converted to "intptr_t" when
+-// using "%x".
++// Format pointers which change size between 32- and 64-bit.
+ #ifdef _LP64
+-#define PTR_FORMAT PTR64_FORMAT
+-#define UINTX_FORMAT UINT64_FORMAT
+-#define INTX_FORMAT INT64_FORMAT
+-#define SIZE_FORMAT UINT64_FORMAT
+-#define SSIZE_FORMAT INT64_FORMAT
++#define INTPTR_FORMAT "0x%016" PRIxPTR
++#define PTR_FORMAT "0x%016" PRIxPTR
+ #else // !_LP64
+-#define PTR_FORMAT PTR32_FORMAT
+-#define UINTX_FORMAT UINT32_FORMAT
+-#define INTX_FORMAT INT32_FORMAT
+-#define SIZE_FORMAT UINT32_FORMAT
+-#define SSIZE_FORMAT INT32_FORMAT
++#define INTPTR_FORMAT "0x%08" PRIxPTR
++#define PTR_FORMAT "0x%08" PRIxPTR
+ #endif // _LP64
+
+-#define INTPTR_FORMAT PTR_FORMAT
++#define SSIZE_FORMAT "%" PRIdPTR
++#define SIZE_FORMAT "%" PRIuPTR
++#define SSIZE_FORMAT_W(width) "%" #width PRIdPTR
++#define SIZE_FORMAT_W(width) "%" #width PRIuPTR
++
++#define INTX_FORMAT "%" PRIdPTR
++#define UINTX_FORMAT "%" PRIuPTR
++#define INTX_FORMAT_W(width) "%" #width PRIdPTR
++#define UINTX_FORMAT_W(width) "%" #width PRIuPTR
++
+
+ // Enable zap-a-lot if in debug version.
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -74,8 +74,25 @@
+ # ifdef SOLARIS_MUTATOR_LIBTHREAD
+ # include <sys/procfs.h>
+ # endif
++
++#include <inttypes.h>
++
++// Solaris 8 doesn't provide definitions of these
++#ifdef SOLARIS
++#ifndef PRIdPTR
++#if defined(_LP64)
++#define PRIdPTR "ld"
++#define PRIuPTR "lu"
++#define PRIxPTR "lx"
++#else
++#define PRIdPTR "d"
++#define PRIuPTR "u"
++#define PRIxPTR "x"
++#endif
++#endif
++#endif
++
+ #ifdef LINUX
+-# include <inttypes.h>
+ # include <signal.h>
+ # include <ucontext.h>
+ # include <sys/time.h>
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -207,6 +207,20 @@
+ // Formatting.
+ #define FORMAT64_MODIFIER "I64"
+
++// Visual Studio doesn't provide inttypes.h so provide appropriate definitions here.
++// The 32 bits ones might need I32 but seem to work ok without it.
++#define PRId32 "d"
++#define PRIu32 "u"
++#define PRIx32 "x"
++
++#define PRId64 "I64d"
++#define PRIu64 "I64u"
++#define PRIx64 "I64x"
++
++#define PRIdPTR "d"
++#define PRIuPTR "u"
++#define PRIxPTR "x"
++
+ #define offset_of(klass,field) offsetof(klass,field)
+
+ #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/growableArray.cpp openjdk/hotspot/src/share/vm/utilities/growableArray.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/growableArray.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/growableArray.cpp 2013-04-08 01:49:33.654322648 +0100
+@@ -34,6 +34,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+ #ifdef ASSERT
+ void GenericGrowableArray::set_nesting() {
+ if (on_stack()) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/histogram.hpp openjdk/hotspot/src/share/vm/utilities/histogram.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/histogram.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/histogram.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ // This class provides a framework for collecting various statistics.
+ // The current implementation is oriented towards counting invocations
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/macros.hpp openjdk/hotspot/src/share/vm/utilities/macros.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/macros.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/macros.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -161,6 +161,14 @@
+ #define NOT_WINDOWS(code) code
+ #endif
+
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
++#define BSD_ONLY(code) code
++#define NOT_BSD(code)
++#else
++#define BSD_ONLY(code)
++#define NOT_BSD(code) code
++#endif
++
+ #ifdef _WIN64
+ #define WIN64_ONLY(code) code
+ #define NOT_WIN64(code)
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/ostream.cpp openjdk/hotspot/src/share/vm/utilities/ostream.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/ostream.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/ostream.cpp 2013-04-08 01:49:33.654322648 +0100
+@@ -39,6 +39,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "os_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "os_bsd.inline.hpp"
++#endif
+
+ extern "C" void jio_print(const char* s); // Declarationtion of jvm method
+
+@@ -992,7 +995,7 @@
+
+ #ifndef PRODUCT
+
+-#if defined(SOLARIS) || defined(LINUX)
++#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/preserveException.hpp openjdk/hotspot/src/share/vm/utilities/preserveException.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/preserveException.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/preserveException.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // This file provides more support for exception handling; see also exceptions.hpp
+ class PreserveExceptionMark {
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/taskqueue.cpp openjdk/hotspot/src/share/vm/utilities/taskqueue.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/taskqueue.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/taskqueue.cpp 2013-04-08 01:49:33.654322648 +0100
+@@ -37,6 +37,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ #ifdef TRACESPINNING
+ uint ParallelTaskTerminator::_total_yields = 0;
+@@ -274,4 +277,3 @@
+ reset_for_reuse();
+ _n_threads = n_threads;
+ }
+-
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/taskqueue.hpp openjdk/hotspot/src/share/vm/utilities/taskqueue.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/taskqueue.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/taskqueue.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -53,6 +53,12 @@
+ #ifdef TARGET_OS_ARCH_linux_ppc
+ # include "orderAccess_linux_ppc.inline.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_x86
++# include "orderAccess_bsd_x86.inline.hpp"
++#endif
++#ifdef TARGET_OS_ARCH_bsd_zero
++# include "orderAccess_bsd_zero.inline.hpp"
++#endif
+
+ // Simple TaskQueue stats that are collected by default in debug builds.
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/vmError.cpp openjdk/hotspot/src/share/vm/utilities/vmError.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/vmError.cpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp 2013-04-08 01:49:33.654322648 +0100
+@@ -45,13 +45,18 @@
+ "JAVA_HOME", "JRE_HOME", "JAVA_TOOL_OPTIONS", "_JAVA_OPTIONS", "CLASSPATH",
+ "JAVA_COMPILER", "PATH", "USERNAME",
+
+- // Env variables that are defined on Solaris/Linux
++ // Env variables that are defined on Solaris/Linux/BSD
+ "LD_LIBRARY_PATH", "LD_PRELOAD", "SHELL", "DISPLAY",
+ "HOSTTYPE", "OSTYPE", "ARCH", "MACHTYPE",
+
+ // defined on Linux
+ "LD_ASSUME_KERNEL", "_JAVA_SR_SIGNUM",
+
++ // defined on Darwin
++ "DYLD_LIBRARY_PATH", "DYLD_FALLBACK_LIBRARY_PATH",
++ "DYLD_FRAMEWORK_PATH", "DYLD_FALLBACK_FRAMEWORK_PATH",
++ "DYLD_INSERT_LIBRARIES",
++
+ // defined on Windows
+ "OS", "PROCESSOR_IDENTIFIER", "_ALT_JAVA_HOME_DIR",
+
+@@ -979,7 +984,7 @@
+ const char* ptr = OnError;
+ while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){
+ out.print_raw ("# Executing ");
+-#if defined(LINUX)
++#if defined(LINUX) || defined(_ALLBSD_SOURCE)
+ out.print_raw ("/bin/sh -c ");
+ #elif defined(SOLARIS)
+ out.print_raw ("/usr/bin/sh -c ");
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/workgroup.hpp openjdk/hotspot/src/share/vm/utilities/workgroup.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/workgroup.hpp 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/src/share/vm/utilities/workgroup.hpp 2013-04-08 01:49:33.654322648 +0100
+@@ -35,6 +35,9 @@
+ #ifdef TARGET_OS_FAMILY_windows
+ # include "thread_windows.inline.hpp"
+ #endif
++#ifdef TARGET_OS_FAMILY_bsd
++# include "thread_bsd.inline.hpp"
++#endif
+
+ // Task class hierarchy:
+ // AbstractGangTask
+diff -Nru openjdk.orig/hotspot/test/jprt.config openjdk/hotspot/test/jprt.config
+--- openjdk.orig/hotspot/test/jprt.config 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/test/jprt.config 2013-04-08 01:49:33.658322712 +0100
+@@ -75,8 +75,8 @@
+
+ # Uses 'uname -s', but only expect SunOS or Linux, assume Windows otherwise.
+ osname=`uname -s`
+-if [ "${osname}" = SunOS ] ; then
+-
++case "${osname}" in
++ SunOS )
+ # SOLARIS: Sparc or X86
+ osarch=`uname -p`
+ if [ "${osarch}" = sparc ] ; then
+@@ -100,9 +100,9 @@
+
+ # File creation mask
+ umask 002
++ ;;
+
+-elif [ "${osname}" = Linux ] ; then
+-
++ Linux | Darwin )
+ # Add basic paths
+ path4sdk=/usr/bin:/bin:/usr/sbin:/sbin
+
+@@ -111,9 +111,31 @@
+ fileMustExist "${make}" make
+
+ umask 002
++ ;;
++
++ FreeBSD | OpenBSD )
++ # Add basic paths
++ path4sdk=/usr/bin:/bin:/usr/sbin:/sbin
++
++ # Find GNU make
++ make=/usr/local/bin/gmake
++ fileMustExist "${make}" make
++
++ umask 002
++ ;;
+
+-else
++ NetBSD )
++ # Add basic paths
++ path4sdk=/usr/bin:/bin:/usr/sbin:/sbin
+
++ # Find GNU make
++ make=/usr/pkg/bin/gmake
++ fileMustExist "${make}" make
++
++ umask 002
++ ;;
++
++ * )
+ # Windows: Differs on CYGWIN vs. MKS.
+
+ # We need to determine if we are running a CYGWIN shell or an MKS shell
+@@ -154,8 +176,8 @@
+ if [ "${unix_toolset}" = CYGWIN ] ; then
+ path4sdk="`/usr/bin/cygpath -p ${path4sdk}`"
+ fi
+-
+-fi
++ ;;
++esac
+
+ # Export PATH setting
+ PATH="${path4sdk}"
+diff -Nru openjdk.orig/hotspot/test/Makefile openjdk/hotspot/test/Makefile
+--- openjdk.orig/hotspot/test/Makefile 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/test/Makefile 2013-04-08 01:49:33.658322712 +0100
+@@ -44,6 +44,22 @@
+ ARCH = i586
+ endif
+ endif
++ifeq ($(OSNAME), Darwin)
++ PLATFORM = bsd
++ SLASH_JAVA = /java
++ ARCH = $(shell uname -m)
++ ifeq ($(ARCH), i386)
++ ARCH = i586
++ endif
++endif
++ifeq ($(findstring BSD,$(OSNAME)), BSD)
++ PLATFORM = bsd
++ SLASH_JAVA = /java
++ ARCH = $(shell uname -m)
++ ifeq ($(ARCH), i386)
++ ARCH = i586
++ endif
++endif
+ ifeq ($(OSNAME), Windows_NT)
+ PLATFORM = windows
+ SLASH_JAVA = J:
+diff -Nru openjdk.orig/hotspot/test/runtime/6929067/Test6929067.sh openjdk/hotspot/test/runtime/6929067/Test6929067.sh
+--- openjdk.orig/hotspot/test/runtime/6929067/Test6929067.sh 2013-03-21 15:17:13.000000000 +0000
++++ openjdk/hotspot/test/runtime/6929067/Test6929067.sh 2013-04-08 01:49:33.658322712 +0100
+@@ -29,7 +29,7 @@
+ PS=":"
+ FS="/"
+ ;;
+- SunOS | Windows_* )
++ SunOS | Windows_* | *BSD)
+ NULL=NUL
+ PS=";"
+ FS="\\"
diff --git a/patches/hotspot/zero/7098194-macosx_port.patch b/patches/hotspot/zero/7098194-macosx_port.patch
new file mode 100644
index 0000000..cb2a1e0
--- /dev/null
+++ b/patches/hotspot/zero/7098194-macosx_port.patch
@@ -0,0 +1,11389 @@
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m openjdk/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m
+--- openjdk.orig/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m 2012-07-25 15:27:37.275648905 +0100
+@@ -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);
++}
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/Makefile openjdk/hotspot/agent/src/os/bsd/Makefile
+--- openjdk.orig/hotspot/agent/src/os/bsd/Makefile 2012-07-25 15:14:34.402184943 +0100
++++ openjdk/hotspot/agent/src/os/bsd/Makefile 2012-07-25 15:27:37.275648905 +0100
+@@ -32,7 +32,6 @@
+ 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:]")
+diff -Nru openjdk.orig/hotspot/agent/src/os/bsd/symtab.c openjdk/hotspot/agent/src/os/bsd/symtab.c
+--- openjdk.orig/hotspot/agent/src/os/bsd/symtab.c 2012-07-25 15:14:34.406185013 +0100
++++ openjdk/hotspot/agent/src/os/bsd/symtab.c 2012-07-25 15:27:37.275648905 +0100
+@@ -116,7 +116,7 @@
+
+ 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 @@
+ // 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 @@
+ // 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 @@
+ }
+ }
+ }
++ goto quit;
++
++bad:
++ destroy_symtab(symtab);
++ symtab = NULL;
+
+ quit:
+ if (shbuf) free(shbuf);
+@@ -195,7 +206,7 @@
+ 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 @@
+ return rslt;
+ }
+
+-quit:
+ return 0;
+ }
+
+@@ -228,12 +238,12 @@
+ 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;
+ }
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java 2012-07-25 15:14:34.414185152 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java 2012-07-25 15:27:37.275648905 +0100
+@@ -52,6 +52,8 @@
+ 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
+diff -Nru openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
+--- openjdk.orig/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java 2012-07-25 15:14:34.426185359 +0100
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java 2012-07-25 15:27:37.275648905 +0100
+@@ -43,7 +43,7 @@
+ 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";
+diff -Nru openjdk.orig/hotspot/.hgignore openjdk/hotspot/.hgignore
+--- openjdk.orig/hotspot/.hgignore 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/.hgignore 2012-07-25 15:27:37.247648426 +0100
+@@ -6,3 +6,4 @@
+ ^src/share/tools/IdealGraphVisualizer/build/
+ ^src/share/tools/IdealGraphVisualizer/dist/
+ ^.hgtip
++.DS_Store
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/adlc.make openjdk/hotspot/make/bsd/makefiles/adlc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/adlc.make 2012-07-25 15:14:34.430185427 +0100
++++ openjdk/hotspot/make/bsd/makefiles/adlc.make 2012-07-25 15:27:37.275648905 +0100
+@@ -61,7 +61,9 @@
+
+ # 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 = \
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/buildtree.make openjdk/hotspot/make/bsd/makefiles/buildtree.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/buildtree.make 2012-07-25 15:14:34.434185497 +0100
++++ openjdk/hotspot/make/bsd/makefiles/buildtree.make 2012-07-25 15:27:37.275648905 +0100
+@@ -114,10 +114,12 @@
+ # 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 @@
+ # 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 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ 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 $@
+
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/defs.make openjdk/hotspot/make/bsd/makefiles/defs.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/defs.make 2012-07-25 15:14:34.438185567 +0100
++++ openjdk/hotspot/make/bsd/makefiles/defs.make 2012-07-25 15:27:37.275648905 +0100
+@@ -162,9 +162,19 @@
+ $(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)
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/dtrace.make openjdk/hotspot/make/bsd/makefiles/dtrace.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/dtrace.make 2012-07-25 15:14:34.438185567 +0100
++++ openjdk/hotspot/make/bsd/makefiles/dtrace.make 2012-07-25 15:27:37.275648905 +0100
+@@ -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")
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/gcc.make openjdk/hotspot/make/bsd/makefiles/gcc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/gcc.make 2012-07-25 15:14:34.442185636 +0100
++++ openjdk/hotspot/make/bsd/makefiles/gcc.make 2012-07-25 15:27:37.275648905 +0100
+@@ -30,17 +30,49 @@
+ # 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 @@
+ 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 @@
+
+
+ # 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 @@
+ 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
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/sa.make openjdk/hotspot/make/bsd/makefiles/sa.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/sa.make 2012-07-25 15:14:34.446185705 +0100
++++ openjdk/hotspot/make/bsd/makefiles/sa.make 2012-07-25 15:27:37.275648905 +0100
+@@ -38,18 +38,16 @@
+ 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 @@
+ $(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 @@
+ $(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 @@
+ # 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 @@
+ clean:
+ rm -rf $(SA_CLASSDIR)
+ rm -rf $(GENERATED)/sa-jdi.jar
+- rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
++ rm -rf $(AGENT_FILES_LIST)
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/saproc.make openjdk/hotspot/make/bsd/makefiles/saproc.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/saproc.make 2012-07-25 15:14:34.446185705 +0100
++++ openjdk/hotspot/make/bsd/makefiles/saproc.make 2012-07-25 15:27:37.275648905 +0100
+@@ -40,20 +40,29 @@
+
+ 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 @@
+ 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 @@
+ 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) \
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/top.make openjdk/hotspot/make/bsd/makefiles/top.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/top.make 2012-07-25 15:14:34.454185843 +0100
++++ openjdk/hotspot/make/bsd/makefiles/top.make 2012-07-25 15:27:37.279648973 +0100
+@@ -82,7 +82,7 @@
+ @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 @@
+ 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)
+diff -Nru openjdk.orig/hotspot/make/bsd/makefiles/vm.make openjdk/hotspot/make/bsd/makefiles/vm.make
+--- openjdk.orig/hotspot/make/bsd/makefiles/vm.make 2012-07-25 15:14:34.454185843 +0100
++++ openjdk/hotspot/make/bsd/makefiles/vm.make 2012-07-25 15:27:37.279648973 +0100
+@@ -108,6 +108,7 @@
+
+ # 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 @@
+
+ #----------------------------------------------------------------------
+
++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
+
+diff -Nru openjdk.orig/hotspot/make/defs.make openjdk/hotspot/make/defs.make
+--- openjdk.orig/hotspot/make/defs.make 2012-07-25 15:14:34.458185911 +0100
++++ openjdk/hotspot/make/defs.make 2012-07-25 15:27:37.279648973 +0100
+@@ -281,6 +281,13 @@
+ 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
+diff -Nru openjdk.orig/hotspot/make/Makefile openjdk/hotspot/make/Makefile
+--- openjdk.orig/hotspot/make/Makefile 2012-07-25 15:14:34.462185981 +0100
++++ openjdk/hotspot/make/Makefile 2012-07-25 15:27:37.275648905 +0100
+@@ -471,6 +471,36 @@
+ ($(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 @@
+ 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
+
+diff -Nru openjdk.orig/hotspot/make/templates/bsd-header openjdk/hotspot/make/templates/bsd-header
+--- openjdk.orig/hotspot/make/templates/bsd-header 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/make/templates/bsd-header 1970-01-01 01:00:00.000000000 +0100
+@@ -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.
+diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/jni_x86.h openjdk/hotspot/src/cpu/x86/vm/jni_x86.h
+--- openjdk.orig/hotspot/src/cpu/x86/vm/jni_x86.h 2012-07-25 15:14:34.470186120 +0100
++++ openjdk/hotspot/src/cpu/x86/vm/jni_x86.h 2012-07-25 15:27:37.279648973 +0100
+@@ -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
+
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp openjdk/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp 2012-07-25 15:27:37.279648973 +0100
+@@ -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;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/generateJvmOffsets.h openjdk/hotspot/src/os/bsd/dtrace/generateJvmOffsets.h
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/generateJvmOffsets.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/generateJvmOffsets.h 2012-07-25 15:27:37.279648973 +0100
+@@ -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
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/generateJvmOffsetsMain.c openjdk/hotspot/src/os/bsd/dtrace/generateJvmOffsetsMain.c
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/generateJvmOffsetsMain.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/generateJvmOffsetsMain.c 2012-07-25 15:27:37.279648973 +0100
+@@ -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);
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/hotspot.d openjdk/hotspot/src/os/bsd/dtrace/hotspot.d
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/hotspot.d 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/hotspot.d 2012-07-25 15:27:37.279648973 +0100
+@@ -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
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/hotspot_jni.d openjdk/hotspot/src/os/bsd/dtrace/hotspot_jni.d
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/hotspot_jni.d 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/hotspot_jni.d 2012-07-25 15:27:37.279648973 +0100
+@@ -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
++
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/hs_private.d openjdk/hotspot/src/os/bsd/dtrace/hs_private.d
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/hs_private.d 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/hs_private.d 2012-07-25 15:27:37.279648973 +0100
+@@ -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
++
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/jhelper.d openjdk/hotspot/src/os/bsd/dtrace/jhelper.d
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/jhelper.d 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/jhelper.d 2012-07-25 15:27:37.279648973 +0100
+@@ -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;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/jvm_dtrace.c openjdk/hotspot/src/os/bsd/dtrace/jvm_dtrace.c
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/jvm_dtrace.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/jvm_dtrace.c 2012-07-25 15:27:37.279648973 +0100
+@@ -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;
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/jvm_dtrace.h openjdk/hotspot/src/os/bsd/dtrace/jvm_dtrace.h
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/jvm_dtrace.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/jvm_dtrace.h 2012-07-25 15:27:37.279648973 +0100
+@@ -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_ */
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/libjvm_db.c openjdk/hotspot/src/os/bsd/dtrace/libjvm_db.c
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/libjvm_db.c 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/libjvm_db.c 2012-07-25 15:27:37.279648973 +0100
+@@ -0,0 +1,1548 @@
++/*
++ * 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.
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++// not available on macosx #include <gelf.h>
++
++#include "libjvm_db.h"
++#include "JvmOffsets.h"
++
++#define LIBJVM_SO "libjvm.so"
++
++#if defined(i386) || defined(__i386) || defined(__amd64)
++#ifdef COMPILER2
++#define X86_COMPILER2
++#endif /* COMPILER2 */
++#endif /* i386 */
++
++typedef struct {
++ short vf_cnt; /* number of recognized java vframes */
++ short bci; /* current frame method byte code index */
++ int line; /* current frame method source line */
++ uint64_t new_fp; /* fp for the next frame */
++ uint64_t new_pc; /* pc for the next frame */
++ uint64_t new_sp; /* "raw" sp for the next frame (includes extension by interpreter/adapter */
++ char locinf; /* indicates there is valid location info */
++} Jframe_t;
++
++int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
++ size_t size, Jframe_t *jframe);
++
++int main(int arg) { return arg; }
++
++static int debug = 0;
++
++static void failed(int err, const char * file, int line) {
++ if (debug) {
++ fprintf(stderr, "failed %d at %s:%d\n", err, file, line);
++ }
++}
++
++static void warn(const char * file, int line, const char * msg) {
++ if (debug) {
++ fprintf(stderr, "warning: %s at %s:%d\n", msg, file, line);
++ }
++}
++
++static void warn1(const char * file, int line, const char * msg, intptr_t arg1) {
++ if (debug) {
++ fprintf(stderr, "warning: ");
++ fprintf(stderr, msg, arg1);
++ fprintf(stderr, " at %s:%d\n", file, line);
++ }
++}
++
++#define CHECK_FAIL(err) \
++ if (err != PS_OK) { failed(err, __FILE__, __LINE__); goto fail; }
++#define WARN(msg) warn(__FILE__, __LINE__, msg)
++#define WARN1(msg, arg1) warn1(__FILE__, __LINE__, msg, arg1)
++
++typedef struct VMStructEntry {
++ const char * typeName; /* The type name containing the given field (example: "Klass") */
++ const char * fieldName; /* The field name within the type (example: "_name") */
++ uint64_t address; /* Address of field; only used for static fields */
++ /* ("offset" can not be reused because of apparent SparcWorks compiler bug */
++ /* in generation of initializer data) */
++} VMStructEntry;
++
++/* Prototyping inlined methods */
++
++int sprintf(char *s, const char *format, ...);
++
++#define SZ16 sizeof(int16_t)
++#define SZ32 sizeof(int32_t)
++
++#define COMP_METHOD_SIGN '*'
++
++#define MAX_VFRAMES_CNT 256
++
++typedef struct vframe {
++ uint64_t methodOop;
++ int32_t sender_decode_offset;
++ int32_t methodIdx;
++ int32_t bci;
++ int32_t line;
++} Vframe_t;
++
++typedef struct frame {
++ uintptr_t fp;
++ uintptr_t pc;
++ uintptr_t sp;
++ uintptr_t sender_sp; // The unextended sp of the caller
++} Frame_t;
++
++typedef struct Nmethod_t {
++ struct jvm_agent* J;
++ Jframe_t *jframe;
++
++ uint64_t nm; /* _nmethod */
++ uint64_t pc;
++ uint64_t pc_desc;
++
++ int32_t orig_pc_offset; /* _orig_pc_offset */
++ int32_t instrs_beg; /* _code_offset */
++ int32_t instrs_end;
++ int32_t deopt_beg; /* _deoptimize_offset */
++ int32_t scopes_data_beg; /* _scopes_data_offset */
++ int32_t scopes_data_end;
++ int32_t oops_beg; /* _oops_offset */
++ int32_t oops_end;
++ int32_t scopes_pcs_beg; /* _scopes_pcs_offset */
++ int32_t scopes_pcs_end;
++
++ int vf_cnt;
++ Vframe_t vframes[MAX_VFRAMES_CNT];
++} Nmethod_t;
++
++struct jvm_agent {
++ struct ps_prochandle* P;
++
++ uint64_t nmethod_vtbl;
++ uint64_t CodeBlob_vtbl;
++ uint64_t BufferBlob_vtbl;
++ uint64_t RuntimeStub_vtbl;
++
++ uint64_t Use_Compressed_Oops_address;
++ uint64_t Universe_methodKlassObj_address;
++ uint64_t Universe_narrow_oop_base_address;
++ uint64_t Universe_narrow_oop_shift_address;
++ uint64_t CodeCache_heap_address;
++
++ /* Volatiles */
++ uint8_t Use_Compressed_Oops;
++ uint64_t Universe_methodKlassObj;
++ uint64_t Universe_narrow_oop_base;
++ uint32_t Universe_narrow_oop_shift;
++ uint64_t CodeCache_low;
++ uint64_t CodeCache_high;
++ uint64_t CodeCache_segmap_low;
++ uint64_t CodeCache_segmap_high;
++
++ int32_t SIZE_CodeCache_log2_segment;
++
++ uint64_t methodOopPtr;
++ uint64_t bcx;
++
++ Nmethod_t *N; /*Inlined methods support */
++ Frame_t prev_fr;
++ Frame_t curr_fr;
++};
++
++static int
++read_string(struct ps_prochandle *P,
++ char *buf, /* caller's buffer */
++ size_t size, /* upper limit on bytes to read */
++ uintptr_t addr) /* address in process */
++{
++ int err = PS_OK;
++ while (size-- > 1 && err == PS_OK) {
++ err = ps_pread(P, addr, buf, 1);
++ if (*buf == '\0') {
++ return PS_OK;
++ }
++ addr += 1;
++ buf += 1;
++ }
++ return -1;
++}
++
++static int read_compressed_pointer(jvm_agent_t* J, uint64_t base, uint32_t *ptr) {
++ int err = -1;
++ uint32_t ptr32;
++ err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t));
++ *ptr = ptr32;
++ return err;
++}
++
++static int read_pointer(jvm_agent_t* J, uint64_t base, uint64_t* ptr) {
++ int err = -1;
++ uint32_t ptr32;
++
++ switch (DATA_MODEL) {
++ case PR_MODEL_LP64:
++ err = ps_pread(J->P, base, ptr, sizeof(uint64_t));
++ break;
++ case PR_MODEL_ILP32:
++ err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t));
++ *ptr = ptr32;
++ break;
++ }
++
++ return err;
++}
++
++static int read_string_pointer(jvm_agent_t* J, uint64_t base, const char ** stringp) {
++ uint64_t ptr;
++ int err;
++ char buffer[1024];
++
++ *stringp = NULL;
++ err = read_pointer(J, base, &ptr);
++ CHECK_FAIL(err);
++ if (ptr != 0) {
++ err = read_string(J->P, buffer, sizeof(buffer), ptr);
++ CHECK_FAIL(err);
++ *stringp = strdup(buffer);
++ }
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++static int parse_vmstruct_entry(jvm_agent_t* J, uint64_t base, VMStructEntry* vmp) {
++ uint64_t ptr;
++ int err;
++
++ err = read_string_pointer(J, base + OFFSET_VMStructEntrytypeName, &vmp->typeName);
++ CHECK_FAIL(err);
++ err = read_string_pointer(J, base + OFFSET_VMStructEntryfieldName, &vmp->fieldName);
++ CHECK_FAIL(err);
++ err = read_pointer(J, base + OFFSET_VMStructEntryaddress, &vmp->address);
++ CHECK_FAIL(err);
++
++ return PS_OK;
++
++ fail:
++ if (vmp->typeName != NULL) free((void*)vmp->typeName);
++ if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
++ return err;
++}
++
++static int parse_vmstructs(jvm_agent_t* J) {
++ VMStructEntry vmVar;
++ VMStructEntry* vmp = &vmVar;
++ uint64_t gHotSpotVMStructs;
++ psaddr_t sym_addr;
++ uint64_t base;
++ int err;
++
++ err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
++ CHECK_FAIL(err);
++ err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
++ CHECK_FAIL(err);
++ base = gHotSpotVMStructs;
++
++ err = PS_OK;
++ while (err == PS_OK) {
++ memset(vmp, 0, sizeof(VMStructEntry));
++ err = parse_vmstruct_entry(J, base, vmp);
++ if (err != PS_OK || vmp->typeName == NULL) {
++ break;
++ }
++
++ if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
++ if (strcmp("_heap", vmp->fieldName) == 0) {
++ err = read_pointer(J, vmp->address, &J->CodeCache_heap_address);
++ }
++ } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
++ if (strcmp("_methodKlassObj", vmp->fieldName) == 0) {
++ J->Universe_methodKlassObj_address = vmp->address;
++ }
++ if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
++ J->Universe_narrow_oop_base_address = vmp->address;
++ }
++ if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) {
++ J->Universe_narrow_oop_shift_address = vmp->address;
++ }
++ }
++ CHECK_FAIL(err);
++
++ base += SIZE_VMStructEntry;
++ if (vmp->typeName != NULL) free((void*)vmp->typeName);
++ if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
++ }
++
++ return PS_OK;
++
++ fail:
++ if (vmp->typeName != NULL) free((void*)vmp->typeName);
++ if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
++ return -1;
++}
++
++static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) {
++ psaddr_t sym_addr;
++ int err;
++
++ err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
++ if (err != PS_OK) goto fail;
++ *valuep = sym_addr;
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++static int read_volatiles(jvm_agent_t* J) {
++ uint64_t ptr;
++ int err;
++
++ err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
++ if (err == PS_OK) {
++ err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
++ CHECK_FAIL(err);
++ } else {
++ J->Use_Compressed_Oops = 0;
++ }
++
++ err = read_pointer(J, J->Universe_methodKlassObj_address, &J->Universe_methodKlassObj);
++ CHECK_FAIL(err);
++
++ err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
++ CHECK_FAIL(err);
++
++ err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
++ OFFSET_VirtualSpace_low, &J->CodeCache_low);
++ CHECK_FAIL(err);
++ err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
++ OFFSET_VirtualSpace_high, &J->CodeCache_high);
++ CHECK_FAIL(err);
++ err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
++ OFFSET_VirtualSpace_low, &J->CodeCache_segmap_low);
++ CHECK_FAIL(err);
++ err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
++ OFFSET_VirtualSpace_high, &J->CodeCache_segmap_high);
++ CHECK_FAIL(err);
++
++ err = ps_pread(J->P, J->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size,
++ &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
++ CHECK_FAIL(err);
++
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++
++static int codecache_contains(jvm_agent_t* J, uint64_t ptr) {
++ /* make sure the code cache is up to date */
++ return (J->CodeCache_low <= ptr && ptr < J->CodeCache_high);
++}
++
++static uint64_t segment_for(jvm_agent_t* J, uint64_t p) {
++ return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment;
++}
++
++static uint64_t block_at(jvm_agent_t* J, int i) {
++ return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment);
++}
++
++static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) {
++ int err;
++
++ *startp = 0;
++ if (J->CodeCache_low <= ptr && ptr < J->CodeCache_high) {
++ int32_t used;
++ uint64_t segment = segment_for(J, ptr);
++ uint64_t block = J->CodeCache_segmap_low;
++ uint8_t tag;
++ err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
++ CHECK_FAIL(err);
++ if (tag == 0xff)
++ return PS_OK;
++ while (tag > 0) {
++ err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
++ CHECK_FAIL(err);
++ segment -= tag;
++ }
++ block = block_at(J, segment);
++ err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used));
++ CHECK_FAIL(err);
++ if (used) {
++ *startp = block + SIZE_HeapBlockHeader;
++ }
++ }
++ return PS_OK;
++
++ fail:
++ return -1;
++}
++
++static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) {
++ psaddr_t sym_addr;
++ int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
++ if (err == PS_OK) {
++ err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t));
++ return err;
++ }
++ *valuep = -1;
++ return -1;
++}
++
++jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) {
++ jvm_agent_t* J;
++ int err;
++
++ if (vers != JVM_DB_VERSION) {
++ errno = ENOTSUP;
++ return NULL;
++ }
++
++ J = (jvm_agent_t*)calloc(sizeof(struct jvm_agent), 1);
++
++ debug = getenv("LIBJVMDB_DEBUG") != NULL;
++ if (debug) debug = 3;
++
++ if (debug) {
++ fprintf(stderr, "Jagent_create: debug=%d\n", debug);
++#ifdef X86_COMPILER2
++ fprintf(stderr, "Jagent_create: R_SP=%d, R_FP=%d, POINTER_SIZE=%d\n", R_SP, R_FP, POINTER_SIZE);
++#endif /* X86_COMPILER2 */
++ }
++
++ J->P = P;
++
++ // Initialize the initial previous frame
++
++ J->prev_fr.fp = 0;
++ J->prev_fr.pc = 0;
++ J->prev_fr.sp = 0;
++ J->prev_fr.sender_sp = 0;
++
++ err = find_symbol(J, "__1cHnmethodG__vtbl_", &J->nmethod_vtbl);
++ CHECK_FAIL(err);
++ err = find_symbol(J, "__1cKBufferBlobG__vtbl_", &J->BufferBlob_vtbl);
++ if (err != PS_OK) J->BufferBlob_vtbl = 0;
++ err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl);
++ CHECK_FAIL(err);
++ err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl);
++ CHECK_FAIL(err);
++
++ err = parse_vmstructs(J);
++ CHECK_FAIL(err);
++ err = read_volatiles(J);
++ CHECK_FAIL(err);
++
++ return J;
++
++ fail:
++ Jagent_destroy(J);
++ return NULL;
++}
++
++void Jagent_destroy(jvm_agent_t *J) {
++ if (J != NULL) {
++ free(J);
++ }
++}
++
++static int is_methodOop(jvm_agent_t* J, uint64_t methodOopPtr) {
++ uint64_t klass;
++ int err;
++ // If UseCompressedOops, this was a compressed oop.
++ if (J->Use_Compressed_Oops != 0) {
++ uint32_t cklass;
++ err = read_compressed_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata,
++ &cklass);
++ // decode heap oop, same as oop.inline.hpp
++ klass = (uint64_t)((uintptr_t)J->Universe_narrow_oop_base +
++ ((uintptr_t)cklass << J->Universe_narrow_oop_shift));
++ } else {
++ err = read_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, &klass);
++ }
++ if (err != PS_OK) goto fail;
++ return klass == J->Universe_methodKlassObj;
++
++ fail:
++ return 0;
++}
++
++static int
++name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t size)
++{
++ short nameIndex;
++ short signatureIndex;
++ uint64_t constantPool;
++ uint64_t constMethod;
++ uint64_t nameSymbol;
++ uint64_t signatureSymbol;
++ uint64_t klassPtr;
++ uint64_t klassSymbol;
++ short klassSymbolLength;
++ short nameSymbolLength;
++ short signatureSymbolLength;
++ char * nameString = NULL;
++ char * klassString = NULL;
++ char * signatureString = NULL;
++ int err;
++
++ err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constants, &constantPool);
++ CHECK_FAIL(err);
++ err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constMethod, &constMethod);
++ CHECK_FAIL(err);
++
++ /* To get name string */
++ err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_name_index, &nameIndex, 2);
++ CHECK_FAIL(err);
++ err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol);
++ CHECK_FAIL(err);
++ // The symbol is a CPSlot and has lower bit set to indicate metadata
++ nameSymbol &= (~1); // remove metadata lsb
++ err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
++ CHECK_FAIL(err);
++ nameString = (char*)calloc(nameSymbolLength + 1, 1);
++ err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
++ CHECK_FAIL(err);
++
++ /* To get signature string */
++ err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_signature_index, &signatureIndex, 2);
++ CHECK_FAIL(err);
++ err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol);
++ CHECK_FAIL(err);
++ signatureSymbol &= (~1); // remove metadata lsb
++ err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
++ CHECK_FAIL(err);
++ signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
++ err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
++ CHECK_FAIL(err);
++
++ /* To get klass string */
++ err = read_pointer(J, constantPool + OFFSET_constantPoolOopDesc_pool_holder, &klassPtr);
++ CHECK_FAIL(err);
++ err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
++ CHECK_FAIL(err);
++ klassString = (char*)calloc(klassSymbolLength + 1, 1);
++ err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);
++ CHECK_FAIL(err);
++
++ result[0] = '\0';
++ strncat(result, klassString, size);
++ size -= strlen(klassString);
++ strncat(result, ".", size);
++ size -= 1;
++ strncat(result, nameString, size);
++ size -= strlen(nameString);
++ strncat(result, signatureString, size);
++
++ if (nameString != NULL) free(nameString);
++ if (klassString != NULL) free(klassString);
++ if (signatureString != NULL) free(signatureString);
++
++ return PS_OK;
++
++ fail:
++ if (debug) {
++ fprintf(stderr, "name_for_methodOop: FAIL \n\n");
++ }
++ if (nameString != NULL) free(nameString);
++ if (klassString != NULL) free(klassString);
++ if (signatureString != NULL) free(signatureString);
++ return -1;
++}
++
++static int nmethod_info(Nmethod_t *N)
++{
++ jvm_agent_t *J = N->J;
++ uint64_t nm = N->nm;
++ int32_t err;
++
++ if (debug > 2 )
++ fprintf(stderr, "\t nmethod_info: BEGIN \n");
++
++ /* Instructions */
++ err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
++ CHECK_FAIL(err);
++
++ /* Oops */
++ err = ps_pread(J->P, nm + OFFSET_nmethod_oops_offset, &N->oops_beg, SZ32);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->oops_end, SZ32);
++ CHECK_FAIL(err);
++
++ /* scopes_pcs */
++ err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32);
++ CHECK_FAIL(err);
++ err = ps_pread(J->P, nm + OFFSET_nmethod_handler_table_offset, &N->scopes_pcs_end, SZ32);
++ CHECK_FAIL(err);
++
++ /* scopes_data */
++ err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->scopes_data_beg, SZ32);
++ CHECK_FAIL(err);
++
++ if (debug > 2 ) {
++ N->scopes_data_end = N->scopes_pcs_beg;
++
++ fprintf(stderr, "\t nmethod_info: instrs_beg: %#x, instrs_end: %#x\n",
++ N->instrs_beg, N->instrs_end);
++
++ fprintf(stderr, "\t nmethod_info: deopt_beg: %#x \n",
++ N->deopt_beg);
++
++ fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n",
++ N->orig_pc_offset);
++
++ fprintf(stderr, "\t nmethod_info: oops_beg: %#x, oops_end: %#x\n",
++ N->oops_beg, N->oops_end);
++
++ fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n",
++ N->scopes_data_beg, N->scopes_data_end);
++
++ fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n",
++ N->scopes_pcs_beg, N->scopes_pcs_end);
++
++ fprintf(stderr, "\t nmethod_info: END \n\n");
++ }
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++static int
++raw_read_int(jvm_agent_t* J, uint64_t *buffer, int32_t *val)
++{
++ int shift = 0;
++ int value = 0;
++ uint8_t ch = 0;
++ int32_t err;
++ int32_t sum;
++ // Constants for UNSIGNED5 coding of Pack200
++ // see compressedStream.hpp
++ enum {
++ lg_H = 6,
++ H = 1<<lg_H,
++ BitsPerByte = 8,
++ L = (1<<BitsPerByte)-H,
++ };
++ int i;
++
++ err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t));
++ CHECK_FAIL(err);
++ if (debug > 2)
++ fprintf(stderr, "\t\t\t raw_read_int: *buffer: %#llx, ch: %#x\n", *buffer, ch);
++
++ sum = ch;
++ if ( sum >= L ) {
++ int32_t lg_H_i = lg_H;
++ // Read maximum of 5 total bytes (we've already read 1).
++ // See CompressedReadStream::read_int_mb
++ for ( i = 0; i < 4; i++) {
++ err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t));
++ CHECK_FAIL(err);
++ sum += ch << lg_H_i;
++ if (ch < L ) {
++ *val = sum;
++ return PS_OK;
++ }
++ lg_H_i += lg_H;
++ }
++ }
++ *val = sum;
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++static int
++read_pair(jvm_agent_t* J, uint64_t *buffer, int32_t *bci, int32_t *line)
++{
++ uint8_t next = 0;
++ int32_t bci_delta;
++ int32_t line_delta;
++ int32_t err;
++
++ if (debug > 2)
++ fprintf(stderr, "\t\t read_pair: BEGIN\n");
++
++ err = ps_pread(J->P, (*buffer)++, &next, sizeof(uint8_t));
++ CHECK_FAIL(err);
++
++ if (next == 0) {
++ if (debug > 2)
++ fprintf(stderr, "\t\t read_pair: END: next == 0\n");
++ return 1; /* stream terminated */
++ }
++ if (next == 0xFF) {
++ if (debug > 2)
++ fprintf(stderr, "\t\t read_pair: END: next == 0xFF\n");
++
++ /* Escape character, regular compression used */
++
++ err = raw_read_int(J, buffer, &bci_delta);
++ CHECK_FAIL(err);
++
++ err = raw_read_int(J, buffer, &line_delta);
++ CHECK_FAIL(err);
++
++ *bci += bci_delta;
++ *line += line_delta;
++
++ if (debug > 2) {
++ fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n",
++ line_delta, bci_delta);
++ fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n",
++ *line, *bci);
++ }
++ } else {
++ /* Single byte compression used */
++ *bci += next >> 3;
++ *line += next & 0x7;
++ if (debug > 2) {
++ fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n",
++ next & 0x7, next >> 3);
++ fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n",
++ *line, *bci);
++ }
++ }
++ if (debug > 2)
++ fprintf(stderr, "\t\t read_pair: END\n");
++ return PS_OK;
++
++ fail:
++ if (debug)
++ fprintf(stderr, "\t\t read_pair: FAIL\n");
++ return err;
++}
++
++static int
++line_number_from_bci(jvm_agent_t* J, Vframe_t *vf)
++{
++ uint64_t buffer;
++ uint16_t code_size;
++ uint64_t code_end_delta;
++ uint64_t constMethod;
++ int8_t access_flags;
++ int32_t best_bci = 0;
++ int32_t stream_bci = 0;
++ int32_t stream_line = 0;
++ int32_t err;
++
++ if (debug > 2) {
++ char name[256];
++ err = name_for_methodOop(J, vf->methodOop, name, 256);
++ CHECK_FAIL(err);
++ fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n",
++ name, vf->bci);
++ }
++
++ err = read_pointer(J, vf->methodOop + OFFSET_methodOopDesc_constMethod, &constMethod);
++ CHECK_FAIL(err);
++
++ vf->line = 0;
++ err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_flags, &access_flags, sizeof(int8_t));
++ CHECK_FAIL(err);
++
++ if (!(access_flags & constMethodOopDesc_has_linenumber_table)) {
++ if (debug > 2)
++ fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n");
++ return PS_OK;
++ }
++
++ /* The line numbers are a short array of 2-tuples [start_pc, line_number].
++ * Not necessarily sorted and not necessarily one-to-one.
++ */
++
++ err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_code_size, &code_size, SZ16);
++ CHECK_FAIL(err);
++
++ /* inlined_table_start() */
++ code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0;
++ buffer = constMethod + (uint64_t) SIZE_constMethodOopDesc + (uint64_t) code_size + code_end_delta;
++
++ if (debug > 2) {
++ fprintf(stderr, "\t\t line_number_from_bci: methodOop: %#llx, native: %d\n",
++ vf->methodOop, (access_flags & AccessFlags_NATIVE));
++ fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n",
++ buffer, (int) code_size);
++ }
++
++ while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) {
++ if (stream_bci == vf->bci) {
++ /* perfect match */
++ if (debug > 2)
++ fprintf(stderr, "\t line_number_from_bci: END: exact line: %ld \n\n", vf->line);
++ vf->line = stream_line;
++ return PS_OK;
++ } else {
++ /* update best_bci/line */
++ if (stream_bci < vf->bci && stream_bci >= best_bci) {
++ best_bci = stream_bci;
++ vf->line = stream_line;
++ if (debug > 2) {
++ fprintf(stderr, "\t line_number_from_bci: best_bci: %ld, best_line: %ld\n",
++ best_bci, vf->line);
++ }
++ }
++ }
++ }
++ if (debug > 2)
++ fprintf(stderr, "\t line_number_from_bci: END: line: %ld \n\n", vf->line);
++ return PS_OK;
++
++ fail:
++ if (debug)
++ fprintf(stderr, "\t line_number_from_bci: FAIL\n");
++ return err;
++}
++
++static int
++get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc)
++{
++ int32_t pc_offset;
++ int32_t err;
++
++ err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32);
++ CHECK_FAIL(err);
++
++ *real_pc = N->nm + N->instrs_beg + pc_offset;
++ if (debug > 2) {
++ fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n",
++ pc_offset, *real_pc);
++ }
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++/* Finds a PcDesc with real-pc equal to N->pc */
++static int pc_desc_at(Nmethod_t *N)
++{
++ uint64_t pc_diff;
++ int32_t offs;
++ int32_t err;
++
++ if (debug > 2)
++ fprintf(stderr, "\t pc_desc_at: BEGIN\n");
++
++ N->vf_cnt = 0;
++ N->pc_desc = 0;
++
++ for (offs = N->scopes_pcs_beg; offs < N->scopes_pcs_end; offs += SIZE_PcDesc) {
++ uint64_t pd;
++ uint64_t best_pc_diff = 16; /* some approximation */
++ uint64_t real_pc = 0;
++
++ pd = N->nm + offs;
++ err = get_real_pc(N, pd, &real_pc);
++ CHECK_FAIL(err);
++
++ pc_diff = real_pc - N->pc;
++
++ /* In general, this fragment should work */
++ if (pc_diff == 0) {
++ N->pc_desc = pd;
++ if (debug) {
++ fprintf(stderr, "\t pc_desc_at: END: pc_desc: FOUND: %#lx \n\n", pd);
++ }
++ return PS_OK;
++ }
++ /* This fragment is to be able to find out an appropriate
++ * pc_desc entry even if pc_desc info is inaccurate.
++ */
++ if (best_pc_diff > pc_diff && pc_diff > 0) {
++ best_pc_diff = pc_diff;
++ N->pc_desc = pd;
++ }
++ }
++ if (debug) {
++ fprintf(stderr, "\t pc_desc_at: END: pc_desc NOT FOUND");
++ if (pc_diff < 20)
++ fprintf(stderr, ", best pc_diff: %d\n\n", pc_diff);
++ else
++ fprintf(stderr, "\n\n");
++ }
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++static int
++scope_desc_at(Nmethod_t *N, int32_t decode_offset, Vframe_t *vf)
++{
++ uint64_t buffer;
++ int32_t err;
++
++ if (debug > 2) {
++ fprintf(stderr, "\t\t scope_desc_at: BEGIN \n");
++ }
++
++ buffer = N->nm + N->scopes_data_beg + decode_offset;
++
++ err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset);
++ CHECK_FAIL(err);
++
++ err = raw_read_int(N->J, &buffer, &vf->methodIdx);
++ CHECK_FAIL(err);
++
++ err = raw_read_int(N->J, &buffer, &vf->bci);
++ CHECK_FAIL(err);
++
++ if (debug > 2) {
++ fprintf(stderr, "\t\t scope_desc_at: sender_decode_offset: %#x\n",
++ vf->sender_decode_offset);
++ fprintf(stderr, "\t\t scope_desc_at: methodIdx: %d\n", vf->methodIdx);
++ fprintf(stderr, "\t\t scope_desc_at: bci: %d\n", vf->bci);
++
++ fprintf(stderr, "\t\t scope_desc_at: END \n\n");
++ }
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++static int scopeDesc_chain(Nmethod_t *N) {
++ int32_t decode_offset = 0;
++ int32_t err;
++
++ if (debug > 2) {
++ fprintf(stderr, "\t scopeDesc_chain: BEGIN\n");
++ }
++
++ err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset,
++ &decode_offset, SZ32);
++ CHECK_FAIL(err);
++
++ while (decode_offset > 0) {
++ Vframe_t *vf = &N->vframes[N->vf_cnt];
++
++ if (debug > 2) {
++ fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset);
++ }
++
++ err = scope_desc_at(N, decode_offset, vf);
++ CHECK_FAIL(err);
++
++ if (vf->methodIdx > ((N->oops_end - N->oops_beg) / POINTER_SIZE)) {
++ fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops length) !\n");
++ return -1;
++ }
++ err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
++ &vf->methodOop);
++ CHECK_FAIL(err);
++
++ if (vf->methodOop) {
++ N->vf_cnt++;
++ err = line_number_from_bci(N->J, vf);
++ CHECK_FAIL(err);
++ if (debug > 2) {
++ fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n",
++ vf->methodOop, vf->line);
++ }
++ }
++ decode_offset = vf->sender_decode_offset;
++ }
++ if (debug > 2) {
++ fprintf(stderr, "\t scopeDesc_chain: END \n\n");
++ }
++ return PS_OK;
++
++ fail:
++ if (debug) {
++ fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n");
++ }
++ return err;
++}
++
++
++static int
++name_for_nmethod(jvm_agent_t* J,
++ uint64_t nm,
++ uint64_t pc,
++ uint64_t methodOop,
++ char *result,
++ size_t size,
++ Jframe_t *jframe
++) {
++ Nmethod_t *N;
++ Vframe_t *vf;
++ int32_t err;
++ int deoptimized = 0;
++
++ if (debug) {
++ fprintf(stderr, "name_for_nmethod: BEGIN: nmethod: %#llx, pc: %#llx\n", nm, pc);
++ }
++ if (J->N == NULL) {
++ J->N = (Nmethod_t *) malloc(sizeof(Nmethod_t));
++ }
++ memset(J->N, 0, sizeof(Nmethod_t)); /* Initial stat: all values are zeros */
++ N = J->N;
++ N->J = J;
++ N->nm = nm;
++ N->pc = pc;
++ N->jframe = jframe;
++
++ err = nmethod_info(N);
++ CHECK_FAIL(err);
++ if (debug) {
++ fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc: %#llx\n",
++ pc, N->nm + N->deopt_beg);
++ }
++
++ /* check for a deoptimized frame */
++ if ( pc == N->nm + N->deopt_beg) {
++ uint64_t base;
++ if (debug) {
++ fprintf(stderr, "name_for_nmethod: found deoptimized frame\n");
++ }
++ if (J->prev_fr.sender_sp != 0) {
++ base = J->prev_fr.sender_sp + N->orig_pc_offset;
++ } else {
++ base = J->curr_fr.sp + N->orig_pc_offset;
++ }
++ err = read_pointer(J, base, &N->pc);
++ CHECK_FAIL(err);
++ if (debug) {
++ fprintf(stderr, "name_for_nmethod: found deoptimized frame converting pc from %#8llx to %#8llx\n",
++ pc, N->pc);
++ }
++ deoptimized = 1;
++ }
++
++ err = pc_desc_at(N);
++ CHECK_FAIL(err);
++
++ if (N->pc_desc > 0) {
++ jframe->locinf = 1;
++ err = scopeDesc_chain(N);
++ CHECK_FAIL(err);
++ }
++ result[0] = COMP_METHOD_SIGN;
++ vf = &N->vframes[0];
++ if (N->vf_cnt > 0) {
++ jframe->vf_cnt = N->vf_cnt;
++ jframe->bci = vf->bci;
++ jframe->line = vf->line;
++ err = name_for_methodOop(J, N->vframes[0].methodOop, result+1, size-1);
++ CHECK_FAIL(err);
++ } else {
++ err = name_for_methodOop(J, methodOop, result+1, size-1);
++ CHECK_FAIL(err);
++ }
++ if (deoptimized) {
++ strncat(result + 1, " [deoptimized frame]; ", size-1);
++ } else {
++ strncat(result + 1, " [compiled] ", size-1);
++ }
++ if (debug)
++ fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n",
++ result, N->vf_cnt);
++ return PS_OK;
++
++ fail:
++ if (debug)
++ fprintf(stderr, "name_for_nmethod: FAIL \n\n");
++ return err;
++}
++
++int is_bci(intptr_t bcx) {
++ switch (DATA_MODEL) {
++ case PR_MODEL_LP64:
++ return ((uintptr_t) bcx) <= ((uintptr_t) MAX_METHOD_CODE_SIZE) ;
++ case PR_MODEL_ILP32:
++ default:
++ return 0 <= bcx && bcx <= MAX_METHOD_CODE_SIZE;
++ }
++}
++
++static int
++name_for_imethod(jvm_agent_t* J,
++ uint64_t bcx,
++ uint64_t methodOop,
++ char *result,
++ size_t size,
++ Jframe_t *jframe
++) {
++ uint64_t bci;
++ uint64_t constMethod;
++ Vframe_t vframe = {0};
++ Vframe_t *vf = &vframe;
++ int32_t err;
++
++ err = read_pointer(J, methodOop + OFFSET_methodOopDesc_constMethod, &constMethod);
++ CHECK_FAIL(err);
++
++ bci = is_bci(bcx) ? bcx : bcx - (constMethod + (uint64_t) SIZE_constMethodOopDesc);
++
++ if (debug)
++ fprintf(stderr, "\t name_for_imethod: BEGIN: methodOop: %#llx\n", methodOop);
++
++ err = name_for_methodOop(J, methodOop, result, size);
++ CHECK_FAIL(err);
++ if (debug)
++ fprintf(stderr, "\t name_for_imethod: method name: %s\n", result);
++
++ if (bci > 0) {
++ vf->methodOop = methodOop;
++ vf->bci = bci;
++ err = line_number_from_bci(J, vf);
++ CHECK_FAIL(err);
++ }
++ jframe->bci = vf->bci;
++ jframe->line = vf->line;
++ jframe->locinf = 1;
++
++ if (debug) {
++ fprintf(stderr, "\t name_for_imethod: END: bci: %d, line: %d\n\n",
++ vf->bci, vf->line);
++ }
++ return PS_OK;
++
++ fail:
++ if (debug)
++ fprintf(stderr, "\t name_for_imethod: FAIL\n");
++ return err;
++}
++
++static int
++name_for_codecache(jvm_agent_t* J, uint64_t fp, uint64_t pc, char * result,
++ size_t size, Jframe_t *jframe, int* is_interpreted)
++{
++ uint64_t start;
++ uint64_t vtbl;
++ int32_t err;
++ *is_interpreted = 0;
++
++ result[0] = '\0';
++
++ err = find_start(J, pc, &start);
++ CHECK_FAIL(err);
++
++ err = read_pointer(J, start, &vtbl);
++ CHECK_FAIL(err);
++
++ if (vtbl == J->nmethod_vtbl) {
++ uint64_t methodOop;
++
++ err = read_pointer(J, start + OFFSET_nmethod_method, &methodOop);
++ CHECK_FAIL(err);
++
++ if (debug) {
++ fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, methodOop: %#8llx \n",
++ start, pc, methodOop);
++ }
++ err = name_for_nmethod(J, start, pc, methodOop, result, size, jframe);
++ CHECK_FAIL(err);
++ } else if (vtbl == J->BufferBlob_vtbl) {
++ const char * name;
++
++ err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
++
++ /*
++ * Temporary usage of string "Interpreter".
++ * We need some other way to distinguish "StubRoutines"
++ * and regular interpreted frames.
++ */
++ if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) {
++ *is_interpreted = 1;
++ if (is_methodOop(J, J->methodOopPtr)) {
++ return name_for_imethod(J, J->bcx, J->methodOopPtr, result, size, jframe);
++ }
++ }
++
++ if (err == PS_OK) {
++ strncpy(result, name, size);
++ free((void*)name);
++ } else {
++ strncpy(result, "<unknown BufferBlob>", size);
++ }
++ /* return PS_OK; */
++ } else {
++ const char * name;
++
++ err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
++ if (err == PS_OK) {
++ strncpy(result, name, size);
++ free((void*)name);
++ } else {
++ strncpy(result, "<unknown CodeBlob>", size);
++ WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl);
++ }
++ }
++ result[size-1] = '\0';
++
++#ifdef X86_COMPILER2
++ if (vtbl != J->RuntimeStub_vtbl) {
++ uint64_t trial_pc;
++ int frame_size;
++ err = ps_pread(J->P, start + OFFSET_CodeBlob_frame_size,
++ &frame_size, SZ32);
++ CHECK_FAIL(err);
++
++ // frame_size is in words, we want bytes.
++ frame_size *= POINTER_SIZE; /* word => byte conversion */
++
++ /*
++ Because c2 doesn't use FP as a framepointer the value of sp/fp we receive
++ in the initial entry to a set of stack frames containing server frames
++ will pretty much be nonsense. We can detect that nonsense by looking to
++ see if the PC we received is correct if we look at the expected storage
++ location in relation to the FP (ie. POINTER_SIZE(FP) )
++ */
++
++ err = read_pointer(J, fp + POINTER_SIZE , &trial_pc);
++ if ( (err != PS_OK || trial_pc != pc) && frame_size > 0 ) {
++ // Either we couldn't even read at the "fp" or the pc didn't match
++ // both are sure clues that the fp is bogus. We no search the stack
++ // for a reasonable number of words trying to find the bogus fp
++ // and the current pc in adjacent words. The we will be able to
++ // deduce an approximation of the frame pointer and actually get
++ // the correct stack pointer. Which we can then unwind for the
++ // next frame.
++ int i;
++ uint64_t check;
++ uint64_t base = J->curr_fr.sp;
++ uint64_t prev_fp = 0;
++ for ( i = 0; i < frame_size * 5 ; i++, base += POINTER_SIZE ) {
++ err = read_pointer(J, base , &check);
++ CHECK_FAIL(err);
++ if (check == fp) {
++ base += POINTER_SIZE;
++ err = read_pointer(J, base , &check);
++ CHECK_FAIL(err);
++ if (check == pc) {
++ if (debug) {
++ fprintf(stderr, "name_for_codecache: found matching fp/pc combo at 0x%llx\n", base - POINTER_SIZE);
++ }
++ prev_fp = base - 2 * POINTER_SIZE;
++ break;
++ }
++ }
++ }
++ if ( prev_fp != 0 ) {
++ // real_sp is the sp we should have received for this frame
++ uint64_t real_sp = prev_fp + 2 * POINTER_SIZE;
++ // +POINTER_SIZE because callee owns the return address so caller's sp is +1 word
++ jframe->new_sp = real_sp + frame_size + POINTER_SIZE;
++ err = read_pointer(J, jframe->new_sp - POINTER_SIZE , &jframe->new_pc);
++ CHECK_FAIL(err);
++ err = read_pointer(J, jframe->new_sp - 2*POINTER_SIZE, &jframe->new_fp);
++ CHECK_FAIL(err);
++ return PS_OK;
++ }
++ }
++
++ /* A prototype to workaround FP absence */
++ /*
++ * frame_size can be 0 for StubRoutines (1) frame.
++ * In this case it should work with fp as usual.
++ */
++ if (frame_size > 0) {
++ jframe->new_fp = J->prev_fr.fp + frame_size;
++ jframe->new_sp = jframe->new_fp + 2 * POINTER_SIZE;
++ } else {
++ memset(&J->curr_fr, 0, sizeof(Frame_t));
++ err = read_pointer(J, fp, &jframe->new_fp);
++ CHECK_FAIL(err);
++
++ err = read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc);
++ CHECK_FAIL(err);
++ }
++ if (debug) {
++ fprintf(stderr, "name_for_codecache: %s, frame_size=%#lx\n",
++ result, frame_size);
++ fprintf(stderr, "name_for_codecache: prev_fr.fp=%#lx, fp=%#lx\n",
++ J->prev_fr.fp, jframe->new_fp);
++ }
++ }
++#endif /* X86_COMPILER2 */
++
++ return PS_OK;
++
++ fail:
++ return err;
++}
++
++int Jget_vframe(jvm_agent_t* J, int vframe_no,
++ char *name, size_t size, Jframe_t *jframe)
++{
++ Nmethod_t *N = J->N;
++ Vframe_t *vf;
++ int32_t err;
++
++ if (vframe_no >= N->vf_cnt) {
++ (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no);
++ return -1;
++ }
++ vf = N->vframes + vframe_no;
++ name[0] = COMP_METHOD_SIGN;
++ err = name_for_methodOop(J, vf->methodOop, name + 1, size);
++ CHECK_FAIL(err);
++
++ jframe->bci = vf->bci;
++ jframe->line = vf->line;
++ if (debug) {
++ fprintf(stderr, "\t Jget_vframe: method name: %s, line: %ld\n",
++ name, vf->line);
++ }
++ return PS_OK;
++
++ fail:
++ if (debug) {
++ fprintf(stderr, "\t Jget_vframe: FAIL\n");
++ }
++ return err;
++}
++
++#define MAX_SYM_SIZE 256
++
++int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
++ size_t size, Jframe_t *jframe) {
++ uintptr_t fp;
++ uintptr_t pc;
++ /* arguments given to read_pointer need to be worst case sized */
++ uint64_t methodOopPtr = 0;
++ uint64_t sender_sp;
++ uint64_t bcx = 0;
++ int is_interpreted = 0;
++ int result = PS_OK;
++ int err = PS_OK;
++
++ if (J == NULL) {
++ return -1;
++ }
++
++ jframe->vf_cnt = 1;
++ jframe->new_fp = 0;
++ jframe->new_pc = 0;
++ jframe->line = 0;
++ jframe->bci = 0;
++ jframe->locinf = 0;
++
++ read_volatiles(J);
++ pc = (uintptr_t) regs[R_PC];
++ J->curr_fr.pc = pc;
++ J->curr_fr.fp = regs[R_FP];
++ J->curr_fr.sp = regs[R_SP];
++
++ if (debug)
++ fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc);
++
++#if defined(sparc) || defined(__sparc)
++ /* The following workaround is for SPARC. CALL instruction occupates 8 bytes.
++ * In the pcDesc structure return pc offset is recorded for CALL instructions.
++ * regs[R_PC] contains a CALL instruction pc offset.
++ */
++ pc += 8;
++ bcx = (uintptr_t) regs[R_L1];
++ methodOopPtr = (uintptr_t) regs[R_L2];
++ sender_sp = regs[R_I5];
++ if (debug > 2) {
++ fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n",
++ regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]);
++ }
++#elif defined(i386) || defined(__i386) || defined(__amd64)
++
++ fp = (uintptr_t) regs[R_FP];
++ if (J->prev_fr.fp == 0) {
++#ifdef X86_COMPILER2
++ /* A workaround for top java frames */
++ J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE);
++#else
++ J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE);
++#endif /* COMPILER2 */
++ }
++ if (debug > 2) {
++ printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp);
++ }
++
++ if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodOopPtr) != PS_OK) {
++ methodOopPtr = 0;
++ }
++ if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) {
++ sender_sp = 0;
++ }
++ if (read_pointer(J, fp + OFFSET_interpreter_frame_bcx_offset, &bcx) != PS_OK) {
++ bcx = 0;
++ }
++#endif /* i386 */
++
++ J->methodOopPtr = methodOopPtr;
++ J->bcx = bcx;
++
++ /* On x86 with C2 JVM: native frame may have wrong regs[R_FP]
++ * For example: JVM_SuspendThread frame poins to the top interpreted frame.
++ * If we call is_methodOop(J, methodOopPtr) before codecache_contains(J, pc)
++ * then we go over and omit both: nmethod and I2CAdapter frames.
++ * Note, that regs[R_PC] is always correct if frame defined correctly.
++ * So it is better to call codecache_contains(J, pc) from the beginning.
++ */
++#ifndef X86_COMPILER2
++ if (is_methodOop(J, J->methodOopPtr)) {
++ result = name_for_imethod(J, bcx, J->methodOopPtr, name, size, jframe);
++ /* If the methodOopPtr is a method then this is highly likely to be
++ an interpreter frame */
++ if (result >= 0) {
++ is_interpreted = 1;
++ }
++ } else
++#endif /* ! X86_COMPILER2 */
++
++ if (codecache_contains(J, pc)) {
++ result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted);
++ }
++#ifdef X86_COMPILER2
++ else if (is_methodOop(J, J->methodOopPtr)) {
++ result = name_for_imethod(J, bcx, J->methodOopPtr, name, size, jframe);
++ /* If the methodOopPtr is a method then this is highly likely to be
++ an interpreter frame */
++ if (result >= 0) {
++ is_interpreted = 1;
++ }
++ }
++#endif /* X86_COMPILER2 */
++ else {
++ if (debug) {
++ fprintf(stderr, "Jlookup_by_regs: END with -1\n\n");
++ }
++ result = -1;
++ }
++ if (!is_interpreted) {
++ sender_sp = 0;
++ }
++ J->curr_fr.sender_sp = sender_sp;
++
++#ifdef X86_COMPILER2
++ if (!J->curr_fr.fp) {
++ J->curr_fr.fp = (jframe->new_fp) ? jframe->new_fp : (uintptr_t)regs[R_FP];
++ }
++ if (!jframe->new_pc && jframe->new_fp) {
++ // This seems dubious
++ read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc);
++ CHECK_FAIL(err);
++ if (debug > 2) {
++ printf("Jlookup_by_regs: (update pc) jframe->new_fp: %#llx, jframe->new_pc: %#llx\n",
++ jframe->new_fp, jframe->new_pc);
++ }
++ }
++
++#endif /* X86_COMPILER2 */
++ J->prev_fr = J->curr_fr;
++
++ if (debug)
++ fprintf(stderr, "Jlookup_by_regs: END\n\n");
++
++ return result;
++
++ fail:
++ return err;
++}
++
++void update_gregs(prgregset_t gregs, Jframe_t jframe) {
++#ifdef X86_COMPILER2
++ if (debug > 0) {
++ fprintf(stderr, "update_gregs: before update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
++ }
++ /*
++ * A workaround for java C2 frames with unconventional FP.
++ * may have to modify regset with new values for FP/PC/SP when needed.
++ */
++ if (jframe.new_sp) {
++ *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) jframe.new_sp;
++ } else {
++ // *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) gregs[R_FP] + 2 * POINTER_SIZE;
++ }
++
++ if (jframe.new_fp) {
++ *((uintptr_t *) &gregs[R_FP]) = (uintptr_t) jframe.new_fp;
++ }
++ if (jframe.new_pc) {
++ *((uintptr_t *) &gregs[R_PC]) = (uintptr_t) jframe.new_pc;
++ }
++ if (debug > 0) {
++ fprintf(stderr, "update_gregs: after update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
++ }
++#endif /* X86_COMPILER2 */
++}
++
++/*
++ * Iterates over java frames at current location given by 'gregs'.
++ *
++ * Returns -1 if no java frames are present or if an error is encountered.
++ * Returns the result of calling 'func' if the return value is non-zero.
++ * Returns 0 otherwise.
++ */
++int Jframe_iter(jvm_agent_t *J, prgregset_t gregs, java_stack_f *func, void* cld) {
++ char buf[MAX_SYM_SIZE + 1];
++ Jframe_t jframe;
++ int i = 0, res;
++#ifdef X86_COMPILER2
++ if (debug > 0) {
++ fprintf(stderr, "Jframe_iter: Entry sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]);
++ }
++#endif /* X86_COMPILER2 */
++
++ memset(&jframe, 0, sizeof(Jframe_t));
++ memset(buf, 0, sizeof(buf));
++ res = Jlookup_by_regs(J, gregs, buf, sizeof(buf), &jframe);
++ if (res != PS_OK)
++ return (-1);
++
++
++ res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1,
++ jframe.line, NULL);
++ if (res != 0) {
++ update_gregs(gregs, jframe);
++ return (res);
++ }
++ for (i = 1; i < jframe.vf_cnt; i++) {
++ Jget_vframe(J, i, buf, sizeof(buf), &jframe);
++ res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1,
++ jframe.line, NULL);
++ if (res != 0) {
++ update_gregs(gregs, jframe);
++ return (res);
++ }
++ }
++ update_gregs(gregs, jframe);
++ return (0);
++}
+diff -Nru openjdk.orig/hotspot/src/os/bsd/dtrace/libjvm_db.h openjdk/hotspot/src/os/bsd/dtrace/libjvm_db.h
+--- openjdk.orig/hotspot/src/os/bsd/dtrace/libjvm_db.h 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/os/bsd/dtrace/libjvm_db.h 2012-07-25 15:27:37.279648973 +0100
+@@ -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
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp openjdk/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp 2012-07-25 15:14:34.482186327 +0100
++++ openjdk/hotspot/src/os/bsd/vm/dtraceJSDT_bsd.cpp 2012-07-25 15:27:37.279648973 +0100
+@@ -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) {
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/jvm_bsd.h openjdk/hotspot/src/os/bsd/vm/jvm_bsd.h
+--- openjdk.orig/hotspot/src/os/bsd/vm/jvm_bsd.h 2012-07-25 15:14:34.486186395 +0100
++++ openjdk/hotspot/src/os/bsd/vm/jvm_bsd.h 2012-07-25 15:27:37.279648973 +0100
+@@ -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 */
+diff -Nru openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.cpp openjdk/hotspot/src/os/bsd/vm/os_bsd.cpp
+--- openjdk.orig/hotspot/src/os/bsd/vm/os_bsd.cpp 2012-07-25 15:14:34.494186535 +0100
++++ openjdk/hotspot/src/os/bsd/vm/os_bsd.cpp 2012-07-25 15:27:37.283649042 +0100
+@@ -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 @@
+ }
+ #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 @@
+ #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 @@
+ 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 @@
+ * 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 @@
+ * 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 @@
+ /* 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 @@
+ * 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 @@
+ }
+ }
+
++#ifdef __APPLE__
++#undef SYS_EXTENSIONS_DIR
++#endif
+ #undef malloc
+ #undef getenv
+ #undef EXTENSIONS_DIR
+@@ -884,6 +938,16 @@
+ #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 @@
+ // 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 @@
+
+ // 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 @@
+ // 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 @@
+ #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 @@
+ 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
+diff -Nru openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+--- openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp 2012-07-25 15:14:34.502186673 +0100
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2012-07-25 15:27:37.283649042 +0100
+@@ -4387,6 +4387,11 @@
+ 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;
+diff -Nru openjdk.orig/hotspot/src/os/solaris/vm/os_solaris.cpp openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp
+--- openjdk.orig/hotspot/src/os/solaris/vm/os_solaris.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp 2012-07-25 15:27:37.283649042 +0100
+@@ -669,6 +669,11 @@
+ 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.
+diff -Nru openjdk.orig/hotspot/src/os/windows/vm/os_windows.cpp openjdk/hotspot/src/os/windows/vm/os_windows.cpp
+--- openjdk.orig/hotspot/src/os/windows/vm/os_windows.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/os/windows/vm/os_windows.cpp 2012-07-25 15:27:37.283649042 +0100
+@@ -710,6 +710,11 @@
+ }
+ }
+
++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;
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s 2012-07-25 15:14:34.510186811 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s 2012-07-25 15:27:37.283649042 +0100
+@@ -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 @@
+ ## 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 @@
+
+
+ .globl SYMBOL(SpinPause)
+- ELF_TYPE(SpinPause,@function)
++ ELF_TYPE(SpinPause,@function)
+ .p2align 4,,15
+ SYMBOL(SpinPause):
+ rep
+@@ -94,7 +94,7 @@
+ # 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 @@
+ 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 @@
+ #
+ # 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 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ # 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 @@
+ 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 @@
+ 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 @@
+ # 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 @@
+ 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 @@
+ 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 @@
+ # 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 @@
+ 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 @@
+ popl %edi
+ popl %esi
+ ret
+- .=.+10
++ .space 10
+ 2: subl %esi,%edi
+ jmp 4f
+ .p2align 4,,15
+@@ -510,7 +510,7 @@
+ popl %edi
+ popl %esi
+ ret
+-
++
+ # Support for void Copy::conjoint_jlongs_atomic(jlong* from,
+ # jlong* to,
+ # size_t count)
+@@ -529,7 +529,7 @@
+ # }
+ # }
+ .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 @@
+ # 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 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ # 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 @@
+ # 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)
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp openjdk/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 2012-07-25 15:14:34.514186879 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 2012-07-25 15:27:37.283649042 +0100
+@@ -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 @@
+ }
+
+ 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
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp 2012-07-25 15:14:34.522187019 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp 2012-07-25 15:27:37.283649042 +0100
+@@ -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
+diff -Nru openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp openjdk/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 2012-07-25 15:14:34.522187019 +0100
++++ openjdk/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -169,7 +169,7 @@
+
+ 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 @@
+ // 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 @@
+ }
+ #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 @@
+ 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 @@
+
+ // 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 @@
+ 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 @@
+ 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");
+diff -Nru openjdk.orig/hotspot/src/share/vm/code/nmethod.cpp openjdk/hotspot/src/share/vm/code/nmethod.cpp
+--- openjdk.orig/hotspot/src/share/vm/code/nmethod.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/code/nmethod.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -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 @@
+ 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 @@
+ 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 @@
+ 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()) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/compiler/compileBroker.cpp openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp
+--- openjdk.orig/hotspot/src/share/vm/compiler/compileBroker.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -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 @@
+ 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)
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -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 @@
+ // 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 @@
+ _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 @@
+ // 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 @@
+ _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
+diff -Nru openjdk.orig/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
+--- openjdk.orig/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -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() {
+diff -Nru openjdk.orig/hotspot/src/share/vm/oops/instanceKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp
+--- openjdk.orig/hotspot/src/share/vm/oops/instanceKlass.cpp 2012-07-25 15:14:34.550187503 +0100
++++ openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -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_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
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/opto/connode.cpp openjdk/hotspot/src/share/vm/opto/connode.cpp
+--- openjdk.orig/hotspot/src/share/vm/opto/connode.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/opto/connode.cpp 2012-07-25 15:27:37.287649111 +0100
+@@ -721,12 +721,7 @@
+ 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
+ }
+
+ //=============================================================================
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jni.cpp openjdk/hotspot/src/share/vm/prims/jni.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/jni.cpp 2012-07-25 15:14:34.558187641 +0100
++++ openjdk/hotspot/src/share/vm/prims/jni.cpp 2012-07-25 15:29:05.953165893 +0100
+@@ -110,6 +110,7 @@
+ // return_value = 5;
+ // return return_value;
+ // JNI_END
++#ifndef USDT2
+ #define DT_RETURN_MARK_DECL(name, type) \
+ HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type); \
+ DTRACE_ONLY( \
+@@ -134,6 +135,30 @@
+ } \
+ )
+
++#else /* USDT2 */
++
++#define DT_RETURN_MARK_DECL(name, type, probe) \
++ DTRACE_ONLY( \
++ class DTraceReturnProbeMark_##name { \
++ public: \
++ const type& _ret_ref; \
++ DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {} \
++ ~DTraceReturnProbeMark_##name() { \
++ probe; \
++ } \
++ } \
++ )
++// Void functions are simpler since there's no return value
++#define DT_VOID_RETURN_MARK_DECL(name, probe) \
++ DTRACE_ONLY( \
++ class DTraceReturnProbeMark_##name { \
++ public: \
++ ~DTraceReturnProbeMark_##name() { \
++ probe; \
++ } \
++ } \
++ )
++#endif /* USDT2 */
+
+ // Place these macros in the function to mark the return. Non-void
+ // functions need the type and address of the return value.
+@@ -162,9 +187,15 @@
+
+ // Choose DT_RETURN_MARK macros based on the type: float/double -> void
+ // (dtrace doesn't do FP yet)
++#ifndef USDT2
+ #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \
+ FP_SELECT(TypeName, \
+ DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) )
++#else /* USDT2 */
++#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe) \
++ FP_SELECT(TypeName, \
++ DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
++#endif /* USDT2 */
+ #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
+ FP_SELECT(TypeName, \
+ DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
+@@ -323,14 +354,24 @@
+
+ // Implementation of JNI entries
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(DefineClass, jclass);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(DefineClass, jclass
++ , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,
+ const jbyte *buf, jsize bufLen))
+ JNIWrapper("DefineClass");
+
++#ifndef USDT2
+ DTRACE_PROBE5(hotspot_jni, DefineClass__entry,
+ env, name, loaderRef, buf, bufLen);
++#else /* USDT2 */
++ HOTSPOT_JNI_DEFINECLASS_ENTRY(
++ env, (char*) name, loaderRef, (char*) buf, bufLen);
++#endif /* USDT2 */
+ jclass cls = NULL;
+ DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
+
+@@ -376,11 +417,21 @@
+
+ static bool first_time_FindClass = true;
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(FindClass, jclass);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(FindClass, jclass
++ , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
+ JNIWrapper("FindClass");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);
++#else /* USDT2 */
++ HOTSPOT_JNI_FINDCLASS_ENTRY(
++ env, (char *)name);
++#endif /* USDT2 */
+
+ jclass result = NULL;
+ DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
+@@ -444,11 +495,21 @@
+ return result;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
++ , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
+ JNIWrapper("FromReflectedMethod");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method);
++#else /* USDT2 */
++ HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(
++ env, method);
++#endif /* USDT2 */
+ jmethodID ret = NULL;
+ DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
+
+@@ -475,11 +536,21 @@
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
++ , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
+ JNIWrapper("FromReflectedField");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field);
++#else /* USDT2 */
++ HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(
++ env, field);
++#endif /* USDT2 */
+ jfieldID ret = NULL;
+ DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
+
+@@ -514,11 +585,21 @@
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
++ , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
+ JNIWrapper("ToReflectedMethod");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic);
++#else /* USDT2 */
++ HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(
++ env, cls, (uintptr_t) method_id, isStatic);
++#endif /* USDT2 */
+ jobject ret = NULL;
+ DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
+
+@@ -534,11 +615,21 @@
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetSuperclass, jclass);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetSuperclass, jclass
++ , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
+ JNIWrapper("GetSuperclass");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSUPERCLASS_ENTRY(
++ env, sub);
++#endif /* USDT2 */
+ jclass obj = NULL;
+ DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
+
+@@ -567,13 +658,23 @@
+
+ JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
+ JNIWrapper("IsSubclassOf");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(
++ env, sub, super);
++#endif /* USDT2 */
+ oop sub_mirror = JNIHandles::resolve_non_null(sub);
+ oop super_mirror = JNIHandles::resolve_non_null(super);
+ if (java_lang_Class::is_primitive(sub_mirror) ||
+ java_lang_Class::is_primitive(super_mirror)) {
+ jboolean ret = (sub_mirror == super_mirror);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ }
+ klassOop sub_klass = java_lang_Class::as_klassOop(sub_mirror);
+@@ -581,15 +682,30 @@
+ assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
+ jboolean ret = Klass::cast(sub_klass)->is_subtype_of(super_klass) ?
+ JNI_TRUE : JNI_FALSE;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(Throw, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(Throw, jint
++ , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
+ JNIWrapper("Throw");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj);
++#else /* USDT2 */
++ HOTSPOT_JNI_THROW_ENTRY(
++ env, obj);
++#endif /* USDT2 */
+ jint ret = JNI_OK;
+ DT_RETURN_MARK(Throw, jint, (const jint&)ret);
+
+@@ -597,11 +713,21 @@
+ ShouldNotReachHere();
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(ThrowNew, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(ThrowNew, jint
++ , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
+ JNIWrapper("ThrowNew");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message);
++#else /* USDT2 */
++ HOTSPOT_JNI_THROWNEW_ENTRY(
++ env, clazz, (char *) message);
++#endif /* USDT2 */
+ jint ret = JNI_OK;
+ DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
+
+@@ -630,18 +756,33 @@
+
+ JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
+ JNIWrapper("ExceptionOccurred");
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(
++ env);
++#endif /* USDT2 */
+ jni_check_async_exceptions(thread);
+ oop exception = thread->pending_exception();
+ jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
+ JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
+ JNIWrapper("ExceptionDescribe");
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(
++ env);
++#endif /* USDT2 */
+ if (thread->has_pending_exception()) {
+ Handle ex(thread, thread->pending_exception());
+ thread->clear_pending_exception();
+@@ -677,13 +818,23 @@
+ }
+ }
+ }
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN(
++ );
++#endif /* USDT2 */
+ JNI_END
+
+
+ JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env))
+ JNIWrapper("ExceptionClear");
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(
++ env);
++#endif /* USDT2 */
+
+ // The jni code might be using this API to clear java thrown exception.
+ // So just mark jvmti thread exception state as exception caught.
+@@ -692,13 +843,23 @@
+ state->set_exception_caught();
+ }
+ thread->clear_pending_exception();
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, ExceptionClear__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN(
++ );
++#endif /* USDT2 */
+ JNI_END
+
+
+ JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
+ JNIWrapper("FatalError");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);
++#else /* USDT2 */
++ HOTSPOT_JNI_FATALERROR_ENTRY(
++ env, (char *) msg);
++#endif /* USDT2 */
+ tty->print_cr("FATAL ERROR in native method: %s", msg);
+ thread->print_stack();
+ os::abort(); // Dump core and abort
+@@ -707,10 +868,20 @@
+
+ JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
+ JNIWrapper("PushLocalFrame");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity);
++#else /* USDT2 */
++ HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(
++ env, capacity);
++#endif /* USDT2 */
+ //%note jni_11
+ if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
++#else /* USDT2 */
++ HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(
++ (uint32_t)JNI_ERR);
++#endif /* USDT2 */
+ return JNI_ERR;
+ }
+ JNIHandleBlock* old_handles = thread->active_handles();
+@@ -719,14 +890,24 @@
+ new_handles->set_pop_frame_link(old_handles);
+ thread->set_active_handles(new_handles);
+ jint ret = JNI_OK;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
+ JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
+ JNIWrapper("PopLocalFrame");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result);
++#else /* USDT2 */
++ HOTSPOT_JNI_POPLOCALFRAME_ENTRY(
++ env, result);
++#endif /* USDT2 */
+ //%note jni_11
+ Handle result_handle(thread, JNIHandles::resolve(result));
+ JNIHandleBlock* old_handles = thread->active_handles();
+@@ -741,71 +922,141 @@
+ JNIHandleBlock::release_block(old_handles, thread); // may block
+ result = JNIHandles::make_local(thread, result_handle());
+ }
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result);
++#else /* USDT2 */
++ HOTSPOT_JNI_POPLOCALFRAME_RETURN(
++ result);
++#endif /* USDT2 */
+ return result;
+ JNI_END
+
+
+ JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
+ JNIWrapper("NewGlobalRef");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWGLOBALREF_ENTRY(
++ env, ref);
++#endif /* USDT2 */
+ Handle ref_handle(thread, JNIHandles::resolve(ref));
+ jobject ret = JNIHandles::make_global(ref_handle);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWGLOBALREF_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+ // Must be JNI_ENTRY (with HandleMark)
+ JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
+ JNIWrapper("DeleteGlobalRef");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref);
++#else /* USDT2 */
++ HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(
++ env, ref);
++#endif /* USDT2 */
+ JNIHandles::destroy_global(ref);
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_DELETEGLOBALREF_RETURN(
++ );
++#endif /* USDT2 */
+ JNI_END
+
+ JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
+ JNIWrapper("DeleteLocalRef");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj);
++#else /* USDT2 */
++ HOTSPOT_JNI_DELETELOCALREF_ENTRY(
++ env, obj);
++#endif /* USDT2 */
+ JNIHandles::destroy_local(obj);
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_DELETELOCALREF_RETURN(
++ );
++#endif /* USDT2 */
+ JNI_END
+
+ JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
+ JNIWrapper("IsSameObject");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(
++ env, r1, r2);
++#endif /* USDT2 */
+ oop a = JNIHandles::resolve(r1);
+ oop b = JNIHandles::resolve(r2);
+ jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISSAMEOBJECT_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
+ JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
+ JNIWrapper("NewLocalRef");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWLOCALREF_ENTRY(
++ env, ref);
++#endif /* USDT2 */
+ jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWLOCALREF_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+ JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
+ JNIWrapper("EnsureLocalCapacity");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity);
++#else /* USDT2 */
++ HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(
++ env, capacity);
++#endif /* USDT2 */
+ jint ret;
+ if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
+ ret = JNI_OK;
+ } else {
+ ret = JNI_ERR;
+ }
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+ // Return the Handle Type
+ JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
+ JNIWrapper("GetObjectRefType");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(
++ env, obj);
++#endif /* USDT2 */
+ jobjectRefType ret;
+ if (JNIHandles::is_local_handle(thread, obj) ||
+ JNIHandles::is_frame_handle(thread, obj))
+@@ -816,7 +1067,12 @@
+ ret = JNIWeakGlobalRefType;
+ else
+ ret = JNIInvalidRefType;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN(
++ (void *) ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -1167,12 +1423,22 @@
+ return ih;
+ }
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(AllocObject, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(AllocObject, jobject
++ , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
+ JNIWrapper("AllocObject");
+
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz);
++#else /* USDT2 */
++ HOTSPOT_JNI_ALLOCOBJECT_ENTRY(
++ env, clazz);
++#endif /* USDT2 */
+ jobject ret = NULL;
+ DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
+
+@@ -1181,11 +1447,21 @@
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(NewObjectA, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(NewObjectA, jobject
++ , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
+ JNIWrapper("NewObjectA");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWOBJECTA_ENTRY(
++ env, clazz, (uintptr_t) methodID);
++#endif /* USDT2 */
+ jobject obj = NULL;
+ DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
+
+@@ -1197,11 +1473,21 @@
+ return obj;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(NewObjectV, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(NewObjectV, jobject
++ , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
+ JNIWrapper("NewObjectV");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWOBJECTV_ENTRY(
++ env, clazz, (uintptr_t) methodID);
++#endif /* USDT2 */
+ jobject obj = NULL;
+ DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
+
+@@ -1213,11 +1499,21 @@
+ return obj;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(NewObject, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(NewObject, jobject
++ , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
+ JNIWrapper("NewObject");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWOBJECT_ENTRY(
++ env, clazz, (uintptr_t) methodID);
++#endif /* USDT2 */
+ jobject obj = NULL;
+ DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
+
+@@ -1235,17 +1531,32 @@
+
+ JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
+ JNIWrapper("GetObjectClass");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(
++ env, obj);
++#endif /* USDT2 */
+ klassOop k = JNIHandles::resolve_non_null(obj)->klass();
+ jclass ret =
+ (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETOBJECTCLASS_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+ JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
+ JNIWrapper("IsInstanceOf");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISINSTANCEOF_ENTRY(
++ env, obj, clazz);
++#endif /* USDT2 */
+ jboolean ret = JNI_TRUE;
+ if (obj != NULL) {
+ ret = JNI_FALSE;
+@@ -1255,7 +1566,12 @@
+ ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
+ }
+ }
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ISINSTANCEOF_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -1317,9 +1633,19 @@
+ JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
+ const char *name, const char *sig))
+ JNIWrapper("GetMethodID");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETMETHODID_ENTRY(
++ env, clazz, (char *) name, (char *) sig);
++#endif /* USDT2 */
+ jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETMETHODID_RETURN(
++ (uintptr_t) ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -1327,9 +1653,19 @@
+ JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
+ const char *name, const char *sig))
+ JNIWrapper("GetStaticMethodID");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(
++ env, (char *) clazz, (char *) name, (char *)sig);
++#endif /* USDT2 */
+ jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTATICMETHODID_RETURN(
++ (uintptr_t) ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -1339,7 +1675,7 @@
+ // Calling Methods
+ //
+
+-
++#ifndef USDT2
+ #define DEFINE_CALLMETHOD(ResultType, Result, Tag) \
+ \
+ DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\
+@@ -1350,7 +1686,7 @@
+ jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
+ JNIWrapper("Call" XSTR(Result) "Method"); \
+ \
+- DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID);\
++ DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID); \
+ ResultType ret = 0;\
+ DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
+ (const ResultType&)ret);\
+@@ -1370,7 +1706,7 @@
+ jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
+ JNIWrapper("Call" XSTR(Result) "MethodV"); \
+ \
+- DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID);\
++ DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID); \
+ ResultType ret = 0;\
+ DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
+ (const ResultType&)ret);\
+@@ -1386,7 +1722,7 @@
+ JNI_ENTRY(ResultType, \
+ jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
+ JNIWrapper("Call" XSTR(Result) "MethodA"); \
+- DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID);\
++ DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID); \
+ ResultType ret = 0;\
+ DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
+ (const ResultType&)ret);\
+@@ -1414,9 +1750,183 @@
+ DT_VOID_RETURN_MARK_DECL(CallVoidMethodV);
+ DT_VOID_RETURN_MARK_DECL(CallVoidMethodA);
+
++#else /* USDT2 */
++
++#define DEFINE_CALLMETHOD(ResultType, Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \
++ , ReturnProbe); \
++\
++JNI_ENTRY(ResultType, \
++ jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
++ JNIWrapper("Call" XSTR(Result) "Method"); \
++\
++ EntryProbe; \
++ ResultType ret = 0;\
++ DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
++ (const ResultType&)ret);\
++\
++ va_list args; \
++ va_start(args, methodID); \
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherVaArg ap(methodID, args); \
++ jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
++ va_end(args); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHOD(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHOD(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHOD(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
++
++DEFINE_CALLMETHOD(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHOD(jint, Int, T_INT,
++ HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHOD(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_CALLMETHOD(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
++DEFINE_CALLMETHOD(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
++
++#define DEFINE_CALLMETHODV(ResultType, Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \
++ , ReturnProbe); \
++\
++JNI_ENTRY(ResultType, \
++ jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
++ JNIWrapper("Call" XSTR(Result) "MethodV"); \
++\
++ EntryProbe;\
++ ResultType ret = 0;\
++ DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
++ (const ResultType&)ret);\
++\
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherVaArg ap(methodID, args); \
++ jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODV(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODV(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODV(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
++
++DEFINE_CALLMETHODV(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODV(jint, Int, T_INT,
++ HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODV(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_CALLMETHODV(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
++DEFINE_CALLMETHODV(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
++
++#define DEFINE_CALLMETHODA(ResultType, Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \
++ , ReturnProbe); \
++\
++JNI_ENTRY(ResultType, \
++ jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
++ JNIWrapper("Call" XSTR(Result) "MethodA"); \
++ EntryProbe; \
++ ResultType ret = 0;\
++ DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
++ (const ResultType&)ret);\
++\
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherArray ap(methodID, args); \
++ jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODA(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODA(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODA(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
++
++DEFINE_CALLMETHODA(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODA(jint, Int, T_INT,
++ HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLMETHODA(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_CALLMETHODA(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
++DEFINE_CALLMETHODA(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
++
++DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
++DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
++DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
++
++#endif /* USDT2 */
++
+ JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
+ JNIWrapper("CallVoidMethod");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(
++ env, obj, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallVoidMethod);
+
+ va_list args;
+@@ -1430,7 +1940,12 @@
+
+ JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
+ JNIWrapper("CallVoidMethodV");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(
++ env, obj, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallVoidMethodV);
+
+ JavaValue jvalue(T_VOID);
+@@ -1441,7 +1956,12 @@
+
+ JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
+ JNIWrapper("CallVoidMethodA");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(
++ env, obj, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallVoidMethodA);
+
+ JavaValue jvalue(T_VOID);
+@@ -1450,6 +1970,7 @@
+ JNI_END
+
+
++#ifndef USDT2
+ #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \
+ \
+ DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\
+@@ -1522,11 +2043,188 @@
+ DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV);
+ DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA);
+
++#else /* USDT2 */
++
++#define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \
++ , ReturnProbe);\
++\
++JNI_ENTRY(ResultType, \
++ jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
++ JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
++\
++ EntryProbe;\
++ ResultType ret;\
++ DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
++ (const ResultType&)ret);\
++\
++ va_list args; \
++ va_start(args, methodID); \
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherVaArg ap(methodID, args); \
++ jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
++ va_end(args); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHOD(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHOD(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHOD(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))
++
++DEFINE_CALLNONVIRTUALMETHOD(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHOD(jint, Int, T_INT
++ , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHOD(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++// Float and double probes don't return value because dtrace doesn't currently support it
++ HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHOD(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())
++DEFINE_CALLNONVIRTUALMETHOD(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN())
++
++#define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \
++ , ReturnProbe);\
++\
++JNI_ENTRY(ResultType, \
++ jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
++ JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \
++\
++ EntryProbe;\
++ ResultType ret;\
++ DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
++ (const ResultType&)ret);\
++\
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherVaArg ap(methodID, args); \
++ jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODV(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODV(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODV(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))
++
++DEFINE_CALLNONVIRTUALMETHODV(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODV(jint, Int, T_INT
++ , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODV(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++// Float and double probes don't return value because dtrace doesn't currently support it
++ HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODV(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())
++DEFINE_CALLNONVIRTUALMETHODV(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN())
++
++#define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \
++ , ReturnProbe);\
++\
++JNI_ENTRY(ResultType, \
++ jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
++ JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
++\
++ EntryProbe;\
++ ResultType ret;\
++ DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
++ (const ResultType&)ret);\
++\
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherArray ap(methodID, args); \
++ jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODA(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODA(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODA(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))
++
++DEFINE_CALLNONVIRTUALMETHODA(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODA(jint, Int, T_INT
++ , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODA(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++// Float and double probes don't return value because dtrace doesn't currently support it
++ HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref))
++DEFINE_CALLNONVIRTUALMETHODA(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
++DEFINE_CALLNONVIRTUALMETHODA(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
++
++DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
++ , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
++DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
++ , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
++DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
++ , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
++#endif /* USDT2 */
++
+ JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
+ JNIWrapper("CallNonvirtualVoidMethod");
+
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry,
+ env, obj, cls, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(
++ env, obj, cls, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
+
+ va_list args;
+@@ -1541,8 +2239,13 @@
+ JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
+ JNIWrapper("CallNonvirtualVoidMethodV");
+
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry,
+ env, obj, cls, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(
++ env, obj, cls, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);
+
+ JavaValue jvalue(T_VOID);
+@@ -1553,8 +2256,13 @@
+
+ JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))
+ JNIWrapper("CallNonvirtualVoidMethodA");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodA__entry,
+ env, obj, cls, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(
++ env, obj, cls, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);
+ JavaValue jvalue(T_VOID);
+ JNI_ArgumentPusherArray ap(methodID, args);
+@@ -1562,6 +2270,7 @@
+ JNI_END
+
+
++#ifndef USDT2
+ #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag) \
+ \
+ DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType);\
+@@ -1634,9 +2343,190 @@
+ DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV);
+ DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA);
+
++#else /* USDT2 */
++
++#define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \
++ , EntryProbe, ResultProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \
++ , ResultProbe); \
++\
++JNI_ENTRY(ResultType, \
++ jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
++ JNIWrapper("CallStatic" XSTR(Result) "Method"); \
++\
++ EntryProbe; \
++ ResultType ret = 0;\
++ DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
++ (const ResultType&)ret);\
++\
++ va_list args; \
++ va_start(args, methodID); \
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherVaArg ap(methodID, args); \
++ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
++ va_end(args); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHOD(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHOD(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHOD(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));
++
++DEFINE_CALLSTATICMETHOD(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHOD(jint, Int, T_INT
++ , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHOD(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref));
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_CALLSTATICMETHOD(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());
++DEFINE_CALLSTATICMETHOD(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN());
++
++#define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \
++ , EntryProbe, ResultProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \
++ , ResultProbe); \
++\
++JNI_ENTRY(ResultType, \
++ jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
++ JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
++\
++ EntryProbe; \
++ ResultType ret = 0;\
++ DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
++ (const ResultType&)ret);\
++\
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherVaArg ap(methodID, args); \
++ /* Make sure class is initialized before trying to invoke its method */ \
++ KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls))); \
++ Klass::cast(k())->initialize(CHECK_0); \
++ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
++ va_end(args); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODV(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODV(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODV(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));
++
++DEFINE_CALLSTATICMETHODV(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODV(jint, Int, T_INT
++ , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODV(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref));
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_CALLSTATICMETHODV(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());
++DEFINE_CALLSTATICMETHODV(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN());
++
++#define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \
++ , EntryProbe, ResultProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \
++ , ResultProbe); \
++\
++JNI_ENTRY(ResultType, \
++ jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
++ JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
++\
++ EntryProbe; \
++ ResultType ret = 0;\
++ DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
++ (const ResultType&)ret);\
++\
++ JavaValue jvalue(Tag); \
++ JNI_ArgumentPusherArray ap(methodID, args); \
++ jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
++ ret = jvalue.get_##ResultType(); \
++ return ret;\
++JNI_END
++
++// the runtime type of subword integral basic types is integer
++DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN
++ , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODA(jbyte, Byte, T_BYTE
++ , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODA(jchar, Char, T_CHAR
++ , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODA(jshort, Short, T_SHORT
++ , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));
++
++DEFINE_CALLSTATICMETHODA(jobject, Object, T_OBJECT
++ , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODA(jint, Int, T_INT
++ , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));
++DEFINE_CALLSTATICMETHODA(jlong, Long, T_LONG
++ , HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref));
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_CALLSTATICMETHODA(jfloat, Float, T_FLOAT
++ , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
++DEFINE_CALLSTATICMETHODA(jdouble, Double, T_DOUBLE
++ , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
++ HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
++
++DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
++ , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
++DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
++ , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
++DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
++ , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
++#endif /* USDT2 */
++
+ JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
+ JNIWrapper("CallStaticVoidMethod");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(
++ env, cls, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallStaticVoidMethod);
+
+ va_list args;
+@@ -1650,7 +2540,12 @@
+
+ JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
+ JNIWrapper("CallStaticVoidMethodV");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(
++ env, cls, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
+
+ JavaValue jvalue(T_VOID);
+@@ -1661,7 +2556,12 @@
+
+ JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
+ JNIWrapper("CallStaticVoidMethodA");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID);
++#else /* USDT2 */
++ HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(
++ env, cls, (uintptr_t) methodID);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
+
+ JavaValue jvalue(T_VOID);
+@@ -1675,12 +2575,22 @@
+ //
+
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetFieldID, jfieldID);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetFieldID, jfieldID
++ , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
+ const char *name, const char *sig))
+ JNIWrapper("GetFieldID");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETFIELDID_ENTRY(
++ env, clazz, (char *) name, (char *) sig);
++#endif /* USDT2 */
+ jfieldID ret = 0;
+ DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
+
+@@ -1712,7 +2622,12 @@
+
+ JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
+ JNIWrapper("GetObjectField");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(
++ env, obj, (uintptr_t) fieldID);
++#endif /* USDT2 */
+ oop o = JNIHandles::resolve_non_null(obj);
+ klassOop k = o->klass();
+ int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
+@@ -1742,11 +2657,17 @@
+ }
+ }
+ #endif // SERIALGC
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
++#else /* USDT2 */
++HOTSPOT_JNI_GETOBJECTFIELD_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
++#ifndef USDT2
+ #define DEFINE_GETFIELD(Return,Fieldname,Result) \
+ \
+ DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\
+@@ -1780,6 +2701,61 @@
+ DEFINE_GETFIELD(jfloat, float, Float)
+ DEFINE_GETFIELD(jdouble, double, Double)
+
++#else /* USDT2 */
++
++#define DEFINE_GETFIELD(Return,Fieldname,Result \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
++ , ReturnProbe); \
++\
++JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
++ JNIWrapper("Get" XSTR(Result) "Field"); \
++\
++ EntryProbe; \
++ Return ret = 0;\
++ DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
++\
++ oop o = JNIHandles::resolve_non_null(obj); \
++ klassOop k = o->klass(); \
++ int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
++ /* Keep JVMTI addition small and only check enabled flag here. */ \
++ /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
++ /* and creates a ResetNoHandleMark. */ \
++ if (JvmtiExport::should_post_field_access()) { \
++ o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
++ } \
++ ret = o->Fieldname##_field(offset); \
++ return ret; \
++JNI_END
++
++DEFINE_GETFIELD(jboolean, bool, Boolean
++ , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))
++DEFINE_GETFIELD(jbyte, byte, Byte
++ , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))
++DEFINE_GETFIELD(jchar, char, Char
++ , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))
++DEFINE_GETFIELD(jshort, short, Short
++ , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))
++DEFINE_GETFIELD(jint, int, Int
++ , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))
++DEFINE_GETFIELD(jlong, long, Long
++ , HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref))
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_GETFIELD(jfloat, float, Float
++ , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETFLOATFIELD_RETURN())
++DEFINE_GETFIELD(jdouble, double, Double
++ , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())
++#endif /* USDT2 */
++
+ address jni_GetBooleanField_addr() {
+ return (address)jni_GetBooleanField;
+ }
+@@ -1807,7 +2783,12 @@
+
+ JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
+ JNIWrapper("SetObjectField");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value);
++#else /* USDT2 */
++ HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(
++ env, obj, (uintptr_t) fieldID, value);
++#endif /* USDT2 */
+ oop o = JNIHandles::resolve_non_null(obj);
+ klassOop k = o->klass();
+ int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
+@@ -1820,9 +2801,15 @@
+ o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
+ }
+ o->obj_field_put(offset, JNIHandles::resolve(value));
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, SetObjectField__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_SETOBJECTFIELD_RETURN(
++);
++#endif /* USDT2 */
+ JNI_END
+
++#ifndef USDT2
+ #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \
+ \
+ JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
+@@ -1857,12 +2844,74 @@
+ DEFINE_SETFIELD(jfloat, float, Float, 'F', f)
+ DEFINE_SETFIELD(jdouble, double, Double, 'D', d)
+
++#else /* USDT2 */
++
++#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
++ , EntryProbe, ReturnProbe) \
++\
++JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
++ JNIWrapper("Set" XSTR(Result) "Field"); \
++\
++ EntryProbe; \
++\
++ oop o = JNIHandles::resolve_non_null(obj); \
++ klassOop k = o->klass(); \
++ int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
++ /* Keep JVMTI addition small and only check enabled flag here. */ \
++ /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
++ /* and creates a ResetNoHandleMark. */ \
++ if (JvmtiExport::should_post_field_modification()) { \
++ jvalue field_value; \
++ field_value.unionType = value; \
++ o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
++ } \
++ o->Fieldname##_field_put(offset, value); \
++ ReturnProbe; \
++JNI_END
++
++DEFINE_SETFIELD(jboolean, bool, Boolean, 'Z', z
++ , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
++DEFINE_SETFIELD(jbyte, byte, Byte, 'B', b
++ , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETBYTEFIELD_RETURN())
++DEFINE_SETFIELD(jchar, char, Char, 'C', c
++ , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETCHARFIELD_RETURN())
++DEFINE_SETFIELD(jshort, short, Short, 'S', s
++ , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETSHORTFIELD_RETURN())
++DEFINE_SETFIELD(jint, int, Int, 'I', i
++ , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETINTFIELD_RETURN())
++DEFINE_SETFIELD(jlong, long, Long, 'J', j
++ , HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETLONGFIELD_RETURN())
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_SETFIELD(jfloat, float, Float, 'F', f
++ , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_SETFLOATFIELD_RETURN())
++DEFINE_SETFIELD(jdouble, double, Double, 'D', d
++ , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
++ HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())
++#endif /* USDT2 */
++
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(ToReflectedField, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(ToReflectedField, jobject
++ , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
+ JNIWrapper("ToReflectedField");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry,
+ env, cls, fieldID, isStatic);
++#else /* USDT2 */
++ HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(
++ env, cls, (uintptr_t) fieldID, isStatic);
++#endif /* USDT2 */
+ jobject ret = NULL;
+ DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
+
+@@ -1892,12 +2941,22 @@
+ //
+ // Accessing Static Fields
+ //
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
++ , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
+ const char *name, const char *sig))
+ JNIWrapper("GetStaticFieldID");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(
++ env, clazz, (char *) name, (char *) sig);
++#endif /* USDT2 */
+ jfieldID ret = NULL;
+ DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
+
+@@ -1933,7 +2992,12 @@
+
+ JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
+ JNIWrapper("GetStaticObjectField");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(
++ env, clazz, (uintptr_t) fieldID);
++#endif /* USDT2 */
+ #ifndef JNICHECK_KERNEL
+ DEBUG_ONLY(klassOop param_k = jniCheck::validate_class(thread, clazz);)
+ #endif // JNICHECK_KERNEL
+@@ -1945,10 +3009,16 @@
+ JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
+ }
+ jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
+ \
+ DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\
+@@ -1979,10 +3049,58 @@
+ DEFINE_GETSTATICFIELD(jfloat, float, Float)
+ DEFINE_GETSTATICFIELD(jdouble, double, Double)
+
++#else /* USDT2 */
++
++#define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \
++ , EntryProbe, ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \
++ , ReturnProbe); \
++\
++JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
++ JNIWrapper("GetStatic" XSTR(Result) "Field"); \
++ EntryProbe; \
++ Return ret = 0;\
++ DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
++ (const Return&)ret);\
++ JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
++ assert(id->is_static_field_id(), "invalid static field id"); \
++ /* Keep JVMTI addition small and only check enabled flag here. */ \
++ /* jni_GetField_probe() assumes that is okay to create handles. */ \
++ if (JvmtiExport::should_post_field_access()) { \
++ JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
++ } \
++ ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
++ return ret;\
++JNI_END
++
++DEFINE_GETSTATICFIELD(jboolean, bool, Boolean
++ , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))
++DEFINE_GETSTATICFIELD(jbyte, byte, Byte
++ , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref) )
++DEFINE_GETSTATICFIELD(jchar, char, Char
++ , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref) )
++DEFINE_GETSTATICFIELD(jshort, short, Short
++ , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref) )
++DEFINE_GETSTATICFIELD(jint, int, Int
++ , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref) )
++DEFINE_GETSTATICFIELD(jlong, long, Long
++ , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref) )
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_GETSTATICFIELD(jfloat, float, Float
++ , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN() )
++DEFINE_GETSTATICFIELD(jdouble, double, Double
++ , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN() )
++#endif /* USDT2 */
+
+ JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
+ JNIWrapper("SetStaticObjectField");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value);
++#else /* USDT2 */
++ HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(
++ env, clazz, (uintptr_t) fieldID, value);
++#endif /* USDT2 */
+ JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
+ assert(id->is_static_field_id(), "invalid static field id");
+ // Keep JVMTI addition small and only check enabled flag here.
+@@ -1993,10 +3111,16 @@
+ JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);
+ }
+ id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN(
++ );
++#endif /* USDT2 */
+ JNI_END
+
+
++#ifndef USDT2
+ #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \
+ \
+ JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
+@@ -2028,6 +3152,54 @@
+ DEFINE_SETSTATICFIELD(jfloat, float, Float, 'F', f)
+ DEFINE_SETSTATICFIELD(jdouble, double, Double, 'D', d)
+
++#else /* USDT2 */
++
++#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \
++ , EntryProbe, ReturnProbe) \
++\
++JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
++ JNIWrapper("SetStatic" XSTR(Result) "Field"); \
++ EntryProbe; \
++\
++ JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
++ assert(id->is_static_field_id(), "invalid static field id"); \
++ /* Keep JVMTI addition small and only check enabled flag here. */ \
++ /* jni_SetField_probe() assumes that is okay to create handles. */ \
++ if (JvmtiExport::should_post_field_modification()) { \
++ jvalue field_value; \
++ field_value.unionType = value; \
++ JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
++ } \
++ id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
++ ReturnProbe;\
++JNI_END
++
++DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, 'Z', z
++ , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
++ HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
++DEFINE_SETSTATICFIELD(jbyte, byte, Byte, 'B', b
++ , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
++ HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())
++DEFINE_SETSTATICFIELD(jchar, char, Char, 'C', c
++ , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
++ HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())
++DEFINE_SETSTATICFIELD(jshort, short, Short, 'S', s
++ , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
++ HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())
++DEFINE_SETSTATICFIELD(jint, int, Int, 'I', i
++ , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
++ HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())
++DEFINE_SETSTATICFIELD(jlong, long, Long, 'J', j
++ , HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
++ HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN())
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_SETSTATICFIELD(jfloat, float, Float, 'F', f
++ , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
++ HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())
++DEFINE_SETSTATICFIELD(jdouble, double, Double, 'D', d
++ , HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
++ HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN())
++#endif /* USDT2 */
+
+ //
+ // String Operations
+@@ -2035,11 +3207,21 @@
+
+ // Unicode Interface
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(NewString, jstring);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(NewString, jstring
++ , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
+ JNIWrapper("NewString");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWSTRING_ENTRY(
++ env, (uint16_t *) unicodeChars, len);
++#endif /* USDT2 */
+ jstring ret = NULL;
+ DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
+ oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
+@@ -2050,9 +3232,19 @@
+
+ JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
+ JNIWrapper("GetStringLength");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(
++ env, string);
++#endif /* USDT2 */
+ jsize ret = java_lang_String::length(JNIHandles::resolve_non_null(string));
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -2060,7 +3252,12 @@
+ JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
+ JNIEnv *env, jstring string, jboolean *isCopy))
+ JNIWrapper("GetStringChars");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
++ env, string, (uintptr_t *) isCopy);
++#endif /* USDT2 */
+ //%note jni_5
+ if (isCopy != NULL) {
+ *isCopy = JNI_TRUE;
+@@ -2074,31 +3271,56 @@
+ memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
+ }
+ buf[s_len] = 0;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGCHARS_RETURN(
++ buf);
++#endif /* USDT2 */
+ return buf;
+ JNI_END
+
+
+ JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
+ JNIWrapper("ReleaseStringChars");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars);
++#else /* USDT2 */
++ HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(
++ env, str, (uint16_t *) chars);
++#endif /* USDT2 */
+ //%note jni_6
+ if (chars != NULL) {
+ // Since String objects are supposed to be immutable, don't copy any
+ // new data back. A bad user will have to go after the char array.
+ FreeHeap((void*) chars);
+ }
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN(
++);
++#endif /* USDT2 */
+ JNI_END
+
+
+ // UTF Interface
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(NewStringUTF, jstring);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(NewStringUTF, jstring
++ , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
+ JNIWrapper("NewStringUTF");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(
++ env, (char *) bytes);
++#endif /* USDT2 */
+ jstring ret;
+ DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
+
+@@ -2110,43 +3332,83 @@
+
+ JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
+ JNIWrapper("GetStringUTFLength");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(
++ env, string);
++#endif /* USDT2 */
+ jsize ret = java_lang_String::utf8_length(JNIHandles::resolve_non_null(string));
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
+ JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
+ JNIWrapper("GetStringUTFChars");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(
++ env, string, (uintptr_t *) isCopy);
++#endif /* USDT2 */
+ oop java_string = JNIHandles::resolve_non_null(string);
+ size_t length = java_lang_String::utf8_length(java_string);
+ char* result = AllocateHeap(length + 1, "GetStringUTFChars");
+ java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
+ if (isCopy != NULL) *isCopy = JNI_TRUE;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(
++ result);
++#endif /* USDT2 */
+ return result;
+ JNI_END
+
+
+ JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
+ JNIWrapper("ReleaseStringUTFChars");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars);
++#else /* USDT2 */
++ HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(
++ env, str, (char *) chars);
++#endif /* USDT2 */
+ if (chars != NULL) {
+ FreeHeap((char*) chars);
+ }
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return);
++#else /* USDT2 */
++HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN(
++);
++#endif /* USDT2 */
+ JNI_END
+
+
+ JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
+ JNIWrapper("GetArrayLength");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(
++ env, array);
++#endif /* USDT2 */
+ arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
+ assert(a->is_array(), "must be array");
+ jsize ret = a->length();
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETARRAYLENGTH_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -2155,11 +3417,21 @@
+ // Object Array Operations
+ //
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
++ , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
+ JNIWrapper("NewObjectArray");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(
++ env, length, elementClass, initialElement);
++#endif /* USDT2 */
+ jobjectArray ret = NULL;
+ DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
+ KlassHandle ek(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(elementClass)));
+@@ -2177,11 +3449,21 @@
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
++ , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
+ JNIWrapper("GetObjectArrayElement");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(
++ env, array, index);
++#endif /* USDT2 */
+ jobject ret = NULL;
+ DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
+ objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
+@@ -2195,11 +3477,21 @@
+ }
+ JNI_END
+
++#ifndef USDT2
+ DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);
++#else /* USDT2 */
++DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
++ , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
++#endif /* USDT2 */
+
+ JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
+ JNIWrapper("SetObjectArrayElement");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value);
++#else /* USDT2 */
++ HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(
++ env, array, index, value);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(SetObjectArrayElement);
+
+ objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
+@@ -2218,9 +3510,10 @@
+ JNI_END
+
+
++#ifndef USDT2
+ #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \
+ \
+- DT_RETURN_MARK_DECL(New##Result##Array, Return);\
++ DT_RETURN_MARK_DECL(New##Result##Array, Return); \
+ \
+ JNI_ENTRY(Return, \
+ jni_New##Result##Array(JNIEnv *env, jsize len)) \
+@@ -2243,6 +3536,51 @@
+ DEFINE_NEWSCALARARRAY(jfloatArray, new_singleArray, Float)
+ DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double)
+
++#else /* USDT2 */
++
++#define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
++ ,EntryProbe,ReturnProbe) \
++\
++ DT_RETURN_MARK_DECL(New##Result##Array, Return \
++ , ReturnProbe); \
++\
++JNI_ENTRY(Return, \
++ jni_New##Result##Array(JNIEnv *env, jsize len)) \
++ JNIWrapper("New" XSTR(Result) "Array"); \
++ EntryProbe; \
++ Return ret = NULL;\
++ DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
++\
++ oop obj= oopFactory::Allocator(len, CHECK_0); \
++ ret = (Return) JNIHandles::make_local(env, obj); \
++ return ret;\
++JNI_END
++
++DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray, Boolean,
++ HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jbyteArray, new_byteArray, Byte,
++ HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jshortArray, new_shortArray, Short,
++ HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jcharArray, new_charArray, Char,
++ HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jintArray, new_intArray, Int,
++ HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jlongArray, new_longArray, Long,
++ HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jfloatArray, new_singleArray, Float,
++ HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))
++DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double,
++ HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len),
++ HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref))
++#endif /* USDT2 */
+
+ // Return an address which will fault if the caller writes to it.
+
+@@ -2260,6 +3598,7 @@
+ }
+
+
++#ifndef USDT2
+ #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag) \
+ \
+ JNI_QUICK_ENTRY(ElementType*, \
+@@ -2294,7 +3633,62 @@
+ DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float)
+ DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double)
+
++#else /* USDT2 */
++
++#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
++ , EntryProbe, ReturnProbe) \
++\
++JNI_QUICK_ENTRY(ElementType*, \
++ jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
++ JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
++ EntryProbe; \
++ /* allocate an chunk of memory in c land */ \
++ typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
++ ElementType* result; \
++ int len = a->length(); \
++ if (len == 0) { \
++ /* Empty array: legal but useless, can't return NULL. \
++ * Return a pointer to something useless. \
++ * Avoid asserts in typeArrayOop. */ \
++ result = (ElementType*)get_bad_address(); \
++ } else { \
++ result = NEW_C_HEAP_ARRAY(ElementType, len); \
++ /* copy the array to the c chunk */ \
++ memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
++ } \
++ if (isCopy) *isCopy = JNI_TRUE; \
++ ReturnProbe; \
++ return result; \
++JNI_END
++
++DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
++ , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))
++DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
++ , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))
++DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
++ , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result))
++DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char
++ , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))
++DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int
++ , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))
++DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long
++ , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
++// Float and double probes don't return value because dtrace doesn't currently support it
++DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
++ , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
++DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
++ , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
++ HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
++#endif /* USDT2 */
+
++#ifndef USDT2
+ #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag) \
+ \
+ JNI_QUICK_ENTRY(void, \
+@@ -2324,6 +3718,56 @@
+ DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float)
+ DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double)
+
++#else /* USDT2 */
++
++#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
++ , EntryProbe, ReturnProbe);\
++\
++JNI_QUICK_ENTRY(void, \
++ jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
++ ElementType *buf, jint mode)) \
++ JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
++ EntryProbe; \
++ typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
++ int len = a->length(); \
++ if (len != 0) { /* Empty array: nothing to free or copy. */ \
++ if ((mode == 0) || (mode == JNI_COMMIT)) { \
++ memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
++ } \
++ if ((mode == 0) || (mode == JNI_ABORT)) { \
++ FreeHeap(buf); \
++ } \
++ } \
++ ReturnProbe; \
++JNI_END
++
++DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
++ , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
++ HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte
++ , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
++ HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short
++ , HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
++ HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char
++ , HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
++ HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int
++ , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),
++ HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long
++ , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
++ HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float
++ , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
++ HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
++DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double
++ , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
++ HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
++#endif /* USDT2 */
++
++#ifndef USDT2
+ #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
+ DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion);\
+ \
+@@ -2355,6 +3799,59 @@
+ DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float)
+ DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double)
+
++#else /* USDT2 */
++
++#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
++ , EntryProbe, ReturnProbe); \
++ DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
++ , ReturnProbe); \
++\
++JNI_ENTRY(void, \
++jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
++ jsize len, ElementType *buf)) \
++ JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
++ EntryProbe; \
++ DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
++ typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
++ if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
++ THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
++ } else { \
++ if (len > 0) { \
++ int sc = typeArrayKlass::cast(src->klass())->log2_element_size(); \
++ memcpy((u_char*) buf, \
++ (u_char*) src->Tag##_at_addr(start), \
++ len << sc); \
++ } \
++ } \
++JNI_END
++
++DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
++ , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
++ HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
++ , HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
++ HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short
++ , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
++ HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char
++ , HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),
++ HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int
++ , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),
++ HOTSPOT_JNI_GETINTARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long
++ , HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
++ HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
++ , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
++ HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
++DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
++ , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
++ HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
++#endif /* USDT2 */
++
++#ifndef USDT2
+ #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
+ DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion);\
+ \
+@@ -2386,6 +3883,58 @@
+ DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float)
+ DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double)
+
++#else /* USDT2 */
++
++#define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
++ , EntryProbe, ReturnProbe); \
++ DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
++ ,ReturnProbe); \
++\
++JNI_ENTRY(void, \
++jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
++ jsize len, const ElementType *buf)) \
++ JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
++ EntryProbe; \
++ DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
++ typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
++ if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
++ THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
++ } else { \
++ if (len > 0) { \
++ int sc = typeArrayKlass::cast(dst->klass())->log2_element_size(); \
++ memcpy((u_char*) dst->Tag##_at_addr(start), \
++ (u_char*) buf, \
++ len << sc); \
++ } \
++ } \
++JNI_END
++
++DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
++ , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
++ HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte
++ , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
++ HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short
++ , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
++ HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char
++ , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
++ HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int
++ , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),
++ HOTSPOT_JNI_SETINTARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long
++ , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
++ HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float
++ , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
++ HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
++DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
++ , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
++ HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
++#endif /* USDT2 */
++
+
+ //
+ // Interception of natives
+@@ -2467,13 +4016,23 @@
+ return true;
+ }
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(RegisterNatives, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(RegisterNatives, jint
++ , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
+ const JNINativeMethod *methods,
+ jint nMethods))
+ JNIWrapper("RegisterNatives");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);
++#else /* USDT2 */
++ HOTSPOT_JNI_REGISTERNATIVES_ENTRY(
++ env, clazz, (void *) methods, nMethods);
++#endif /* USDT2 */
+ jint ret = 0;
+ DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
+
+@@ -2511,7 +4070,12 @@
+
+ JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
+ JNIWrapper("UnregisterNatives");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz);
++#else /* USDT2 */
++ HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(
++ env, clazz);
++#endif /* USDT2 */
+ klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz));
+ //%note jni_2
+ if (Klass::cast(k)->oop_is_instance()) {
+@@ -2523,7 +4087,12 @@
+ }
+ }
+ }
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0);
++#else /* USDT2 */
++ HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(
++ 0);
++#endif /* USDT2 */
+ return 0;
+ JNI_END
+
+@@ -2531,10 +4100,20 @@
+ // Monitor functions
+ //
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(MonitorEnter, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(MonitorEnter, jint
++ , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj);
++#else /* USDT2 */
++ HOTSPOT_JNI_MONITORENTER_ENTRY(
++ env, jobj);
++#endif /* USDT2 */
+ jint ret = JNI_ERR;
+ DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
+
+@@ -2549,10 +4128,20 @@
+ return ret;
+ JNI_END
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(MonitorExit, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(MonitorExit, jint
++ , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj);
++#else /* USDT2 */
++ HOTSPOT_JNI_MONITOREXIT_ENTRY(
++ env, jobj);
++#endif /* USDT2 */
+ jint ret = JNI_ERR;
+ DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
+
+@@ -2572,11 +4161,21 @@
+ // Extensions
+ //
+
++#ifndef USDT2
+ DT_VOID_RETURN_MARK_DECL(GetStringRegion);
++#else /* USDT2 */
++DT_VOID_RETURN_MARK_DECL(GetStringRegion
++ , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
++#endif /* USDT2 */
+
+ JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
+ JNIWrapper("GetStringRegion");
++#ifndef USDT2
+ DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGREGION_ENTRY(
++ env, string, start, len, buf);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(GetStringRegion);
+ oop s = JNIHandles::resolve_non_null(string);
+ int s_len = java_lang_String::length(s);
+@@ -2591,11 +4190,21 @@
+ }
+ JNI_END
+
++#ifndef USDT2
+ DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);
++#else /* USDT2 */
++DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
++ , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
++#endif /* USDT2 */
+
+ JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
+ JNIWrapper("GetStringUTFRegion");
++#ifndef USDT2
+ DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(
++ env, string, start, len, buf);
++#endif /* USDT2 */
+ DT_VOID_RETURN_MARK(GetStringUTFRegion);
+ oop s = JNIHandles::resolve_non_null(string);
+ int s_len = java_lang_String::length(s);
+@@ -2621,7 +4230,12 @@
+
+ JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
+ JNIWrapper("GetPrimitiveArrayCritical");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(
++ env, array, (uintptr_t *) isCopy);
++#endif /* USDT2 */
+ GC_locker::lock_critical(thread);
+ if (isCopy != NULL) {
+ *isCopy = JNI_FALSE;
+@@ -2635,23 +4249,43 @@
+ type = typeArrayKlass::cast(a->klass())->element_type();
+ }
+ void* ret = arrayOop(a)->base(type);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
+ JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
+ JNIWrapper("ReleasePrimitiveArrayCritical");
++#ifndef USDT2
+ DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
++#else /* USDT2 */
++ HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(
++ env, array, carray, mode);
++#endif /* USDT2 */
+ // The array, carray and mode arguments are ignored
+ GC_locker::unlock_critical(thread);
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
++#else /* USDT2 */
++HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(
++);
++#endif /* USDT2 */
+ JNI_END
+
+
+ JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
+ JNIWrapper("GetStringCritical");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(
++ env, string, (uintptr_t *) isCopy);
++#endif /* USDT2 */
+ GC_locker::lock_critical(thread);
+ if (isCopy != NULL) {
+ *isCopy = JNI_FALSE;
+@@ -2666,44 +4300,89 @@
+ } else {
+ ret = (jchar*) s_value->base(T_CHAR);
+ }
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(
++ (uint16_t *) ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+
+ JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
+ JNIWrapper("ReleaseStringCritical");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
++#else /* USDT2 */
++ HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(
++ env, str, (uint16_t *) chars);
++#endif /* USDT2 */
+ // The str and chars arguments are ignored
+ GC_locker::unlock_critical(thread);
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
++#else /* USDT2 */
++HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(
++);
++#endif /* USDT2 */
+ JNI_END
+
+
+ JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
+ JNIWrapper("jni_NewWeakGlobalRef");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(
++ env, ref);
++#endif /* USDT2 */
+ Handle ref_handle(thread, JNIHandles::resolve(ref));
+ jweak ret = JNIHandles::make_weak_global(ref_handle);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+ // Must be JNI_ENTRY (with HandleMark)
+ JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
+ JNIWrapper("jni_DeleteWeakGlobalRef");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref);
++#else /* USDT2 */
++ HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(
++ env, ref);
++#endif /* USDT2 */
+ JNIHandles::destroy_weak_global(ref);
++#ifndef USDT2
+ DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return);
++#else /* USDT2 */
++ HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN(
++ );
++#endif /* USDT2 */
+ JNI_END
+
+
+ JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
+ JNIWrapper("jni_ExceptionCheck");
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(
++ env);
++#endif /* USDT2 */
+ jni_check_async_exceptions(thread);
+ jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ JNI_END
+
+@@ -2795,11 +4474,21 @@
+ JavaThread* thread = JavaThread::thread_from_jni_environment(env);
+
+ JNIWrapper("jni_NewDirectByteBuffer");
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(
++ env, address, capacity);
++#endif /* USDT2 */
+
+ if (!directBufferSupportInitializeEnded) {
+ if (!initializeDirectBufferSupport(env, thread)) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, (uintptr_t) NULL);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(
++ NULL);
++#endif /* USDT2 */
+ return NULL;
+ }
+ }
+@@ -2810,11 +4499,21 @@
+ // takes int capacity
+ jint cap = (jint) capacity;
+ jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ }
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
++ , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
++#endif /* USDT2 */
+
+ extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
+ {
+@@ -2822,7 +4521,12 @@
+ JavaThread* thread = JavaThread::thread_from_jni_environment(env);
+
+ JNIWrapper("jni_GetDirectBufferAddress");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(
++ env, buf);
++#endif /* USDT2 */
+ void* ret = NULL;
+ DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
+
+@@ -2840,7 +4544,12 @@
+ return ret;
+ }
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
++ , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
+ {
+@@ -2848,7 +4557,12 @@
+ JavaThread* thread = JavaThread::thread_from_jni_environment(env);
+
+ JNIWrapper("jni_GetDirectBufferCapacity");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(
++ env, buf);
++#endif /* USDT2 */
+ jlong ret = -1;
+ DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
+
+@@ -2875,8 +4589,18 @@
+
+ JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
+ JNIWrapper("GetVersion");
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETVERSION_ENTRY(
++ env);
++#endif /* USDT2 */
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETVERSION_RETURN(
++ CurrentVersion);
++#endif /* USDT2 */
+ return CurrentVersion;
+ JNI_END
+
+@@ -2884,9 +4608,19 @@
+
+ JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
+ JNIWrapper("jni_GetJavaVM");
++#ifndef USDT2
+ DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETJAVAVM_ENTRY(
++ env, (void **) vm);
++#endif /* USDT2 */
+ *vm = (JavaVM *)(&main_vm);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETJAVAVM_RETURN(
++ JNI_OK);
++#endif /* USDT2 */
+ return JNI_OK;
+ JNI_END
+
+@@ -3266,11 +5000,21 @@
+ #define JAVASTACKSIZE (400 * 1024) /* Default size of a thread java stack */
+ enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
+
++#ifndef USDT2
+ HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*);
+ DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
++ , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
++#ifndef USDT2
+ HS_DTRACE_PROBE1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, args_);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(
++ args_);
++#endif /* USDT2 */
+ JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
+ jint ret = JNI_ERR;
+ DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
+@@ -3304,11 +5048,21 @@
+
+ #endif
+
++#ifndef USDT2
+ HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
+ DT_RETURN_MARK_DECL(CreateJavaVM, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(CreateJavaVM, jint
++ , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
++#ifndef USDT2
+ HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
++#else /* USDT2 */
++ HOTSPOT_JNI_CREATEJAVAVM_ENTRY(
++ (void **) vm, penv, args);
++#endif /* USDT2 */
+
+ jint result = JNI_ERR;
+ DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
+@@ -3398,31 +5152,53 @@
+ return result;
+ }
+
++#ifndef USDT2
+ HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \
+ JavaVM**, jsize, jsize*);
+ HS_DTRACE_PROBE_DECL1(hotspot_jni, GetCreatedJavaVMs__return, jint);
++#endif /* !USDT2 */
+
+ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
+ // See bug 4367188, the wrapper can sometimes cause VM crashes
+ // JNIWrapper("GetCreatedJavaVMs");
++#ifndef USDT2
+ HS_DTRACE_PROBE3(hotspot_jni, GetCreatedJavaVMs__entry, \
+ vm_buf, bufLen, numVMs);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY(
++ (void **) vm_buf, bufLen, (uintptr_t *) numVMs);
++#endif /* USDT2 */
+ if (vm_created) {
+ if (numVMs != NULL) *numVMs = 1;
+ if (bufLen > 0) *vm_buf = (JavaVM *)(&main_vm);
+ } else {
+ if (numVMs != NULL) *numVMs = 0;
+ }
++#ifndef USDT2
+ HS_DTRACE_PROBE1(hotspot_jni, GetCreatedJavaVMs__return, JNI_OK);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(
++ JNI_OK);
++#endif /* USDT2 */
+ return JNI_OK;
+ }
+
+ extern "C" {
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(DestroyJavaVM, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(DestroyJavaVM, jint
++ , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, DestroyJavaVM__entry, vm);
++#else /* USDT2 */
++ HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(
++ vm);
++#endif /* USDT2 */
+ jint res = JNI_ERR;
+ DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
+
+@@ -3540,7 +5316,7 @@
+ // mark the thread as no longer attaching
+ // this uses a fence to push the change through so we don't have
+ // to regrab the threads_lock
+- thread->set_attached();
++ thread->set_done_attaching_via_jni();
+
+ // Set java thread status.
+ java_lang_Thread::set_thread_status(thread->threadObj(),
+@@ -3568,34 +5344,64 @@
+
+
+ jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, AttachCurrentThread__entry, vm, penv, _args);
++#else /* USDT2 */
++ HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(
++ vm, penv, _args);
++#endif /* USDT2 */
+ if (!vm_created) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, JNI_ERR);
++#else /* USDT2 */
++ HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(
++ (uint32_t) JNI_ERR);
++#endif /* USDT2 */
+ return JNI_ERR;
+ }
+
+ JNIWrapper("AttachCurrentThread");
+ jint ret = attach_current_thread(vm, penv, _args, false);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ }
+
+
+ jint JNICALL jni_DetachCurrentThread(JavaVM *vm) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__entry, vm);
++#else /* USDT2 */
++ HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(
++ vm);
++#endif /* USDT2 */
+ VM_Exit::block_if_vm_exited();
+
+ JNIWrapper("DetachCurrentThread");
+
+ // If the thread has been deattacted the operations is a no-op
+ if (ThreadLocalStorage::thread() == NULL) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
++#else /* USDT2 */
++ HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
++ JNI_OK);
++#endif /* USDT2 */
+ return JNI_OK;
+ }
+
+ JavaThread* thread = JavaThread::current();
+ if (thread->has_last_Java_frame()) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_ERR);
++#else /* USDT2 */
++ HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
++ (uint32_t) JNI_ERR);
++#endif /* USDT2 */
+ // Can't detach a thread that's running java, that can't work.
+ return JNI_ERR;
+ }
+@@ -3616,14 +5422,29 @@
+ thread->exit(false, JavaThread::jni_detach);
+ delete thread;
+
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
++#else /* USDT2 */
++ HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
++ JNI_OK);
++#endif /* USDT2 */
+ return JNI_OK;
+ }
+
++#ifndef USDT2
+ DT_RETURN_MARK_DECL(GetEnv, jint);
++#else /* USDT2 */
++DT_RETURN_MARK_DECL(GetEnv, jint
++ , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
++#endif /* USDT2 */
+
+ jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, GetEnv__entry, vm, penv, version);
++#else /* USDT2 */
++ HOTSPOT_JNI_GETENV_ENTRY(
++ vm, penv, version);
++#endif /* USDT2 */
+ jint ret = JNI_ERR;
+ DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
+
+@@ -3678,15 +5499,30 @@
+
+
+ jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
++#ifndef USDT2
+ DTRACE_PROBE3(hotspot_jni, AttachCurrentThreadAsDaemon__entry, vm, penv, _args);
++#else /* USDT2 */
++ HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(
++ vm, penv, _args);
++#endif /* USDT2 */
+ if (!vm_created) {
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, JNI_ERR);
++#else /* USDT2 */
++ HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(
++ (uint32_t) JNI_ERR);
++#endif /* USDT2 */
+ return JNI_ERR;
+ }
+
+ JNIWrapper("AttachCurrentThreadAsDaemon");
+ jint ret = attach_current_thread(vm, penv, _args, true);
++#ifndef USDT2
+ DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, ret);
++#else /* USDT2 */
++ HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(
++ ret);
++#endif /* USDT2 */
+ return ret;
+ }
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jvm.cpp openjdk/hotspot/src/share/vm/prims/jvm.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/jvm.cpp 2012-07-25 15:14:34.562187710 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvm.cpp 2012-07-25 15:27:37.291649179 +0100
+@@ -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_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 @@
+ // 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 @@
+ // 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 @@
+ }
+ 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_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 ///////////////////////////////////////////////////////////////////////
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/jvm.h openjdk/hotspot/src/share/vm/prims/jvm.h
+--- openjdk.orig/hotspot/src/share/vm/prims/jvm.h 2012-07-25 15:14:34.562187710 +0100
++++ openjdk/hotspot/src/share/vm/prims/jvm.h 2012-07-25 15:27:37.291649179 +0100
+@@ -291,6 +291,9 @@
+ 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);
+diff -Nru openjdk.orig/hotspot/src/share/vm/prims/unsafe.cpp openjdk/hotspot/src/share/vm/prims/unsafe.cpp
+--- openjdk.orig/hotspot/src/share/vm/prims/unsafe.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/prims/unsafe.cpp 2012-07-25 15:27:37.291649179 +0100
+@@ -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_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 @@
+ }
+ }
+ 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
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/arguments.cpp openjdk/hotspot/src/share/vm/runtime/arguments.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/arguments.cpp 2012-07-25 15:14:34.566187778 +0100
++++ openjdk/hotspot/src/share/vm/runtime/arguments.cpp 2012-07-25 15:27:37.291649179 +0100
+@@ -2601,16 +2601,16 @@
+ 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);
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp openjdk/hotspot/src/share/vm/runtime/globals.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp 2012-07-25 15:14:34.570187848 +0100
++++ openjdk/hotspot/src/share/vm/runtime/globals.hpp 2012-07-25 15:27:37.291649179 +0100
+@@ -677,7 +677,7 @@
+ 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)") \
+ \
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/java.cpp openjdk/hotspot/src/share/vm/runtime/java.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/java.cpp 2012-07-25 15:14:34.578187987 +0100
++++ openjdk/hotspot/src/share/vm/runtime/java.cpp 2012-07-25 15:27:37.291649179 +0100
+@@ -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 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) {
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/objectMonitor.cpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/objectMonitor.cpp 2012-07-25 15:14:34.582188056 +0100
++++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -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 @@
+ 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 @@
+ } \
+ }
+
++#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) {;}
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.cpp openjdk/hotspot/src/share/vm/runtime/os.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/os.cpp 2012-07-25 15:14:34.586188125 +0100
++++ openjdk/hotspot/src/share/vm/runtime/os.cpp 2012-07-25 15:28:15.208297999 +0100
+@@ -1098,6 +1098,9 @@
+ "%/lib/netx.jar:"
+ "%/lib/plugin.jar:"
+ "%/lib/rhino.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;
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.hpp openjdk/hotspot/src/share/vm/runtime/os.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/os.hpp 2012-07-25 15:14:34.586188125 +0100
++++ openjdk/hotspot/src/share/vm/runtime/os.hpp 2012-07-25 15:27:37.295649247 +0100
+@@ -184,6 +184,9 @@
+ // 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.
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/sharedRuntime.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/sharedRuntime.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -148,11 +148,13 @@
+
+ #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
+
+@@ -954,8 +956,14 @@
+ 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 +973,18 @@
+ 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 +994,18 @@
+ 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
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/synchronizer.cpp openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/synchronizer.cpp 2012-07-25 15:14:34.590188194 +0100
++++ openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -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 @@
+ 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 @@
+ } \
+ }
+
++#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) {;}
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/thread.cpp openjdk/hotspot/src/share/vm/runtime/thread.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/thread.cpp 2012-07-25 15:14:34.590188194 +0100
++++ openjdk/hotspot/src/share/vm/runtime/thread.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -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 @@
+ 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 @@
+ 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 @@
+ #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 @@
+ 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 @@
+ // 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 @@
+ 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 @@
+ 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 @@
+ // 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();
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/thread.hpp openjdk/hotspot/src/share/vm/runtime/thread.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/thread.hpp 2012-07-25 15:14:34.594188262 +0100
++++ openjdk/hotspot/src/share/vm/runtime/thread.hpp 2012-07-25 15:27:37.295649247 +0100
+@@ -309,6 +309,11 @@
+ 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 @@
+ 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 @@
+
+ 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 @@
+ 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;
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/vmThread.cpp openjdk/hotspot/src/share/vm/runtime/vmThread.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/vmThread.cpp 2012-07-25 15:14:34.598188332 +0100
++++ openjdk/hotspot/src/share/vm/runtime/vmThread.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -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 @@
+ // 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 @@
+
+ {
+ 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!
+diff -Nru openjdk.orig/hotspot/src/share/vm/services/classLoadingService.cpp openjdk/hotspot/src/share/vm/services/classLoadingService.cpp
+--- openjdk.orig/hotspot/src/share/vm/services/classLoadingService.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/services/classLoadingService.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -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 @@
+ 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)
+diff -Nru openjdk.orig/hotspot/src/share/vm/services/memoryManager.cpp openjdk/hotspot/src/share/vm/services/memoryManager.cpp
+--- openjdk.orig/hotspot/src/share/vm/services/memoryManager.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/services/memoryManager.cpp 2012-07-25 15:27:37.295649247 +0100
+@@ -36,10 +36,12 @@
+ #include "services/gcNotifier.hpp"
+ #include "utilities/dtrace.hpp"
+
++#ifndef USDT2
+ HS_DTRACE_PROBE_DECL8(hotspot, mem__pool__gc__begin, char*, int, char*, int,
+ size_t, size_t, size_t, size_t);
+ HS_DTRACE_PROBE_DECL8(hotspot, mem__pool__gc__end, char*, int, char*, int,
+ size_t, size_t, size_t, size_t);
++#endif /* !USDT2 */
+
+ MemoryManager::MemoryManager() {
+ _num_pools = 0;
+@@ -238,11 +240,19 @@
+ MemoryPool* pool = MemoryService::get_memory_pool(i);
+ MemoryUsage usage = pool->get_memory_usage();
+ _current_gc_stat->set_before_gc_usage(i, usage);
++#ifndef USDT2
+ HS_DTRACE_PROBE8(hotspot, mem__pool__gc__begin,
+ name(), strlen(name()),
+ pool->name(), strlen(pool->name()),
+ usage.init_size(), usage.used(),
+ usage.committed(), usage.max_size());
++#else /* USDT2 */
++ HOTSPOT_MEM_POOL_GC_BEGIN(
++ (char *) name(), strlen(name()),
++ (char *) pool->name(), strlen(pool->name()),
++ usage.init_size(), usage.used(),
++ usage.committed(), usage.max_size());
++#endif /* USDT2 */
+ }
+ }
+ }
+@@ -268,11 +278,19 @@
+ MemoryPool* pool = MemoryService::get_memory_pool(i);
+ MemoryUsage usage = pool->get_memory_usage();
+
++#ifndef USDT2
+ HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
+ name(), strlen(name()),
+ pool->name(), strlen(pool->name()),
+ usage.init_size(), usage.used(),
+ usage.committed(), usage.max_size());
++#else /* USDT2 */
++ HOTSPOT_MEM_POOL_GC_END(
++ (char *) name(), strlen(name()),
++ (char *) pool->name(), strlen(pool->name()),
++ usage.init_size(), usage.used(),
++ usage.committed(), usage.max_size());
++#endif /* USDT2 */
+
+ _current_gc_stat->set_after_gc_usage(i, usage);
+ }
+diff -Nru openjdk.orig/hotspot/src/share/vm/services/runtimeService.cpp openjdk/hotspot/src/share/vm/services/runtimeService.cpp
+--- openjdk.orig/hotspot/src/share/vm/services/runtimeService.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/services/runtimeService.cpp 2012-07-25 15:27:37.299649316 +0100
+@@ -30,8 +30,10 @@
+ #include "utilities/dtrace.hpp"
+ #include "utilities/exceptions.hpp"
+
++#ifndef USDT2
+ HS_DTRACE_PROBE_DECL(hs_private, safepoint__begin);
+ HS_DTRACE_PROBE_DECL(hs_private, safepoint__end);
++#endif /* !USDT2 */
+
+ TimeStamp RuntimeService::_app_timer;
+ TimeStamp RuntimeService::_safepoint_timer;
+@@ -108,7 +110,11 @@
+ }
+
+ void RuntimeService::record_safepoint_begin() {
++#ifndef USDT2
+ HS_DTRACE_PROBE(hs_private, safepoint__begin);
++#else /* USDT2 */
++ HS_PRIVATE_SAFEPOINT_BEGIN();
++#endif /* USDT2 */
+
+ // Print the time interval in which the app was executing
+ if (PrintGCApplicationConcurrentTime) {
+@@ -133,7 +139,11 @@
+ }
+
+ void RuntimeService::record_safepoint_end() {
++#ifndef USDT2
+ HS_DTRACE_PROBE(hs_private, safepoint__end);
++#else /* USDT2 */
++ HS_PRIVATE_SAFEPOINT_END();
++#endif /* USDT2 */
+
+ // Print the time interval for which the app was stopped
+ // during the current safepoint operation.
+diff -Nru openjdk.orig/hotspot/src/share/vm/services/threadService.cpp openjdk/hotspot/src/share/vm/services/threadService.cpp
+--- openjdk.orig/hotspot/src/share/vm/services/threadService.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/services/threadService.cpp 2012-07-25 15:27:37.299649316 +0100
+@@ -751,7 +751,7 @@
+ _blocker_object = obj();
+ JavaThread* owner = ObjectSynchronizer::get_lock_owner(obj, false);
+ if ((owner == NULL && _thread_status == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER)
+- || (owner != NULL && owner->is_attaching())) {
++ || (owner != NULL && owner->is_attaching_via_jni())) {
+ // ownership information of the monitor is not available
+ // (may no longer be owned or releasing to some other thread)
+ // make this thread in RUNNABLE state.
+@@ -899,7 +899,7 @@
+ }
+
+ // skip jni threads in the process of attaching
+- if (!include_jni_attaching_threads && jt->is_attaching()) {
++ if (!include_jni_attaching_threads && jt->is_attaching_via_jni()) {
+ continue;
+ }
+
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/debug.cpp openjdk/hotspot/src/share/vm/utilities/debug.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/debug.cpp 2012-07-25 15:14:34.606188471 +0100
++++ openjdk/hotspot/src/share/vm/utilities/debug.cpp 2012-07-25 15:27:37.299649316 +0100
+@@ -209,7 +209,7 @@
+ // Place-holder for non-existent suppression check:
+ #define error_is_suppressed(file_name, line_no) (false)
+
+-#endif //PRODUCT
++#endif // !PRODUCT
+
+ void report_vm_error(const char* file, int line, const char* error_msg,
+ const char* detail_msg)
+@@ -264,7 +264,7 @@
+ void report_untested(const char* file, int line, const char* message) {
+ #ifndef PRODUCT
+ warning("Untested: %s in %s: %d\n", message, file, line);
+-#endif // PRODUCT
++#endif // !PRODUCT
+ }
+
+ void report_out_of_shared_space(SharedSpaceType shared_space) {
+@@ -309,9 +309,6 @@
+ }
+ }
+
+-
+-extern "C" void ps();
+-
+ static bool error_reported = false;
+
+ // call this when the VM is dying--it might loosen some asserts
+@@ -366,11 +363,10 @@
+ default: ShouldNotReachHere();
+ }
+ }
+-#endif // #ifndef PRODUCT
++#endif // !PRODUCT
+
+ // ------ helper functions for debugging go here ------------
+
+-#ifndef PRODUCT
+ // All debug entries should be wrapped with a stack allocated
+ // Command object. It makes sure a resource mark is set and
+ // flushes the logfile to prevent file sharing problems.
+@@ -391,11 +387,17 @@
+ tty->print_cr("\"Executing %s\"", str);
+ }
+
+- ~Command() { tty->flush(); Debugging = debug_save; level--; }
++ ~Command() {
++ tty->flush();
++ Debugging = debug_save;
++ level--;
++ }
+ };
+
+ int Command::level = 0;
+
++#ifndef PRODUCT
++
+ extern "C" void blob(CodeBlob* cb) {
+ Command c("blob");
+ cb->print();
+@@ -478,7 +480,7 @@
+ oop obj = oop(p);
+ obj->print();
+ } else {
+- tty->print("%#p", p);
++ tty->print(PTR_FORMAT, p);
+ }
+ }
+
+@@ -487,7 +489,10 @@
+ extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
+ extern "C" void findpc(intptr_t x);
+
++#endif // !PRODUCT
++
+ extern "C" void ps() { // print stack
++ if (Thread::current() == NULL) return;
+ Command c("ps");
+
+
+@@ -500,6 +505,11 @@
+ if (p->has_last_Java_frame()) {
+ // If the last_Java_fp is set we are in C land and
+ // can call the standard stack_trace function.
++#ifdef PRODUCT
++ p->print_stack();
++ } else {
++ tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
++#else // !PRODUCT
+ p->trace_stack();
+ } else {
+ frame f = os::current_frame();
+@@ -508,6 +518,7 @@
+ tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
+ p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
+ pd_ps(f);
++#endif // PRODUCT
+ }
+
+ }
+@@ -524,6 +535,8 @@
+ }
+ }
+
++#ifndef PRODUCT
++
+ extern "C" void psf() { // print stack frames
+ {
+ Command c("psf");
+@@ -555,12 +568,15 @@
+ SafepointSynchronize::print_state();
+ }
+
++#endif // !PRODUCT
+
+ extern "C" void pss() { // print all stacks
++ if (Thread::current() == NULL) return;
+ Command c("pss");
+- Threads::print(true, true);
++ Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
+ }
+
++#ifndef PRODUCT
+
+ extern "C" void debug() { // to set things up for compiler debugging
+ Command c("debug");
+@@ -911,4 +927,4 @@
+ }
+ #endif
+
+-#endif // PRODUCT
++#endif // !PRODUCT
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/dtrace.hpp openjdk/hotspot/src/share/vm/utilities/dtrace.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/dtrace.hpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/utilities/dtrace.hpp 2012-07-25 15:27:37.299649316 +0100
+@@ -25,7 +25,7 @@
+ #ifndef SHARE_VM_UTILITIES_DTRACE_HPP
+ #define SHARE_VM_UTILITIES_DTRACE_HPP
+
+-#if defined(SOLARIS) && defined(DTRACE_ENABLED)
++#if defined(DTRACE_ENABLED)
+
+ #include <sys/sdt.h>
+
+@@ -36,11 +36,27 @@
+ #define HS_DTRACE_WORKAROUND_TAIL_CALL_BUG() \
+ do { volatile size_t dtrace_workaround_tail_call_bug = 1; } while (0)
+
+-#else // ndef SOLARIS || ndef DTRACE_ENABLED
++#if defined(SOLARIS)
++#define USDT1 1
++#elif defined(__APPLE__)
++#define USDT2 1
++#include <sys/types.h>
++#include "dtracefiles/hotspot.h"
++#include "dtracefiles/hotspot_jni.h"
++#include "dtracefiles/hs_private.h"
++#else
++#error "dtrace enabled for unknown os"
++#endif /* defined(SOLARIS) */
++
++#else /* defined(DTRACE_ENABLED) */
+
+ #define DTRACE_ONLY(x)
+ #define NOT_DTRACE(x) x
+
++#define HS_DTRACE_WORKAROUND_TAIL_CALL_BUG()
++
++#ifndef USDT2
++
+ #define DTRACE_PROBE(a,b) {;}
+ #define DTRACE_PROBE1(a,b,c) {;}
+ #define DTRACE_PROBE2(a,b,c,d) {;}
+@@ -48,9 +64,14 @@
+ #define DTRACE_PROBE4(a,b,c,d,e,f) {;}
+ #define DTRACE_PROBE5(a,b,c,d,e,f,g) {;}
+
+-#define HS_DTRACE_WORKAROUND_TAIL_CALL_BUG()
++#else /* USDT2 */
++
++#include "dtrace_usdt2_disabled.hpp"
++#endif /* USDT2 */
+
+-#endif
++#endif /* defined(DTRACE_ENABLED) */
++
++#ifndef USDT2
+
+ #define HS_DTRACE_PROBE_FN(provider,name)\
+ __dtrace_##provider##___##name
+@@ -133,4 +154,6 @@
+ (uintptr_t)a3,(uintptr_t)a4,(uintptr_t)a5,(uintptr_t)a6,(uintptr_t)a7,\
+ (uintptr_t)a8,(uintptr_t)a9))
+
++#endif /* !USDT2 */
++
+ #endif // SHARE_VM_UTILITIES_DTRACE_HPP
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/dtrace_usdt2_disabled.hpp openjdk/hotspot/src/share/vm/utilities/dtrace_usdt2_disabled.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/dtrace_usdt2_disabled.hpp 1970-01-01 01:00:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/utilities/dtrace_usdt2_disabled.hpp 2012-07-25 15:27:37.299649316 +0100
+@@ -0,0 +1,1097 @@
++/*
++ * Copyright (c) 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.
++ *
++ */
++
++#ifndef SHARE_VM_UTILITIES_DTRACE_USDT2_DISABLED_HPP
++#define SHARE_VM_UTILITIES_DTRACE_USDT2_DISABLED_HPP
++
++/* This file contains dummy provider probes needed when compiling a hotspot
++ * that does not support dtrace probes. This could be because we're building
++ * on a system that doesn't suuport dtrace or because we're bulding a variant
++ * of hotspot (like core) where we do not support dtrace
++ */
++#if !defined(DTRACE_ENABLED)
++
++#ifdef USDT2
++
++/* hotspot provider probes */
++#define HOTSPOT_CLASS_LOADED(arg0, arg1, arg2, arg3)
++#define HOTSPOT_CLASS_LOADED_ENABLED() 0
++#define HOTSPOT_CLASS_UNLOADED(arg0, arg1, arg2, arg3)
++#define HOTSPOT_CLASS_UNLOADED_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_REQUIRED(arg0, arg1, arg2, arg3)
++#define HOTSPOT_CLASS_INITIALIZATION_REQUIRED_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_RECURSIVE(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_RECURSIVE_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_CONCURRENT(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_CONCURRENT_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_ERRONEOUS(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_ERRONEOUS_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_SUPER_FAILED(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_SUPER_FAILED_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_CLINIT(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_CLINIT_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_ERROR(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_ERROR_ENABLED() 0
++#define HOTSPOT_CLASS_INITIALIZATION_END(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_CLASS_INITIALIZATION_END_ENABLED() 0
++#define HOTSPOT_COMPILED_METHOD_LOAD(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
++#define HOTSPOT_COMPILED_METHOD_LOAD_ENABLED() 0
++#define HOTSPOT_COMPILED_METHOD_UNLOAD(arg0, arg1, arg2, arg3, arg4, arg5)
++#define HOTSPOT_COMPILED_METHOD_UNLOAD_ENABLED() 0
++#define HOTSPOT_GC_BEGIN(arg0)
++#define HOTSPOT_GC_BEGIN_ENABLED() 0
++#define HOTSPOT_GC_END()
++#define HOTSPOT_GC_END_ENABLED() 0
++#define HOTSPOT_MEM_POOL_GC_BEGIN(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
++#define HOTSPOT_MEM_POOL_GC_BEGIN_ENABLED() 0
++#define HOTSPOT_MEM_POOL_GC_END(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
++#define HOTSPOT_MEM_POOL_GC_END_ENABLED() 0
++#define HOTSPOT_METHOD_COMPILE_BEGIN(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
++#define HOTSPOT_METHOD_COMPILE_BEGIN_ENABLED() 0
++#define HOTSPOT_METHOD_COMPILE_END(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
++#define HOTSPOT_METHOD_COMPILE_END_ENABLED() 0
++#define HOTSPOT_METHOD_ENTRY(arg0, arg1, arg2, arg3, arg4, arg5, arg6)
++#define HOTSPOT_METHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_METHOD_RETURN(arg0, arg1, arg2, arg3, arg4, arg5, arg6)
++#define HOTSPOT_METHOD_RETURN_ENABLED() 0
++#define HOTSPOT_MONITOR_CONTENDED_ENTER(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_CONTENDED_ENTER_ENABLED() 0
++#define HOTSPOT_MONITOR_CONTENDED_ENTERED(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_CONTENDED_ENTERED_ENABLED() 0
++#define HOTSPOT_MONITOR_CONTENDED_EXIT(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_CONTENDED_EXIT_ENABLED() 0
++#define HOTSPOT_MONITOR_NOTIFY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_NOTIFY_ENABLED() 0
++#define HOTSPOT_MONITOR_NOTIFYALL(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_NOTIFYALL_ENABLED() 0
++#define HOTSPOT_MONITOR_WAIT(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_MONITOR_WAIT_ENABLED() 0
++#define HOTSPOT_MONITOR_WAIT_PROBE(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_WAIT_PROBE_ENABLED() 0
++#define HOTSPOT_MONITOR_WAITED(arg0, arg1, arg2, arg3)
++#define HOTSPOT_MONITOR_WAITED_ENABLED() 0
++#define HOTSPOT_OBJECT_ALLOC(arg0, arg1, arg2, arg3)
++#define HOTSPOT_OBJECT_ALLOC_ENABLED() 0
++#define HOTSPOT_THREAD_START(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_THREAD_START_ENABLED() 0
++#define HOTSPOT_THREAD_STOP(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_THREAD_STOP_ENABLED() 0
++#define HOTSPOT_THREAD_SLEEP_BEGIN(arg0)
++#define HOTSPOT_THREAD_SLEEP_BEGIN_ENABLED() 0
++#define HOTSPOT_THREAD_SLEEP_END(arg0)
++#define HOTSPOT_THREAD_SLEEP_END_ENABLED() 0
++#define HOTSPOT_THREAD_YIELD()
++#define HOTSPOT_THREAD_YIELD_ENABLED() 0
++#define HOTSPOT_THREAD_PARK_BEGIN(arg0, arg1, arg2)
++#define HOTSPOT_THREAD_PARK_BEGIN_ENABLED() 0
++#define HOTSPOT_THREAD_PARK_END(arg0)
++#define HOTSPOT_THREAD_PARK_END_ENABLED() 0
++#define HOTSPOT_THREAD_UNPARK()
++#define HOTSPOT_THREAD_UNPARK_ENABLED() 0
++#define HOTSPOT_VM_INIT_BEGIN()
++#define HOTSPOT_VM_INIT_BEGIN_ENABLED() 0
++#define HOTSPOT_VM_INIT_END()
++#define HOTSPOT_VM_INIT_END_ENABLED() 0
++#define HOTSPOT_VM_SHUTDOWN()
++#define HOTSPOT_VM_SHUTDOWN_ENABLED() 0
++#define HOTSPOT_VMOPS_REQUEST(arg0, arg1, arg2)
++#define HOTSPOT_VMOPS_REQUEST_ENABLED() 0
++#define HOTSPOT_VMOPS_BEGIN(arg0, arg1, arg2)
++#define HOTSPOT_VMOPS_BEGIN_ENABLED() 0
++#define HOTSPOT_VMOPS_END(arg0, arg1, arg2)
++#define HOTSPOT_VMOPS_END_ENABLED() 0
++
++/* hs_private provider probes */
++#define HS_PRIVATE_CMS_INITMARK_BEGIN()
++#define HS_PRIVATE_CMS_INITMARK_BEGIN_ENABLED() 0
++#define HS_PRIVATE_CMS_INITMARK_END()
++#define HS_PRIVATE_CMS_INITMARK_END_ENABLED() 0
++#define HS_PRIVATE_CMS_REMARK_BEGIN()
++#define HS_PRIVATE_CMS_REMARK_BEGIN_ENABLED() 0
++#define HS_PRIVATE_CMS_REMARK_END()
++#define HS_PRIVATE_CMS_REMARK_END_ENABLED() 0
++#define HS_PRIVATE_HASHTABLE_NEW_ENTRY(arg0, arg1, arg2, arg3)
++#define HS_PRIVATE_HASHTABLE_NEW_ENTRY_ENABLED() 0
++#define HS_PRIVATE_SAFEPOINT_BEGIN()
++#define HS_PRIVATE_SAFEPOINT_BEGIN_ENABLED() 0
++#define HS_PRIVATE_SAFEPOINT_END()
++#define HS_PRIVATE_SAFEPOINT_END_ENABLED() 0
++
++/* hotspot_jni provider probes */
++#define HOTSPOT_JNI_ALLOCOBJECT_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_ALLOCOBJECT_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ALLOCOBJECT_RETURN(arg0)
++#define HOTSPOT_JNI_ALLOCOBJECT_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(arg0)
++#define HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(arg0)
++#define HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLBOOLEANMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLBOOLEANMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLBOOLEANMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLBOOLEANMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLBOOLEANMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLBOOLEANMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLBOOLEANMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLBOOLEANMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLBYTEMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLBYTEMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLBYTEMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLBYTEMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLBYTEMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLBYTEMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLBYTEMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLBYTEMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLBYTEMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLCHARMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLCHARMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLCHARMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLCHARMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLCHARMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLCHARMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLCHARMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLCHARMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLCHARMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLCHARMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLCHARMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLDOUBLEMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLDOUBLEMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLDOUBLEMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLDOUBLEMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLFLOATMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLFLOATMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLFLOATMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLFLOATMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLFLOATMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLFLOATMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLFLOATMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLFLOATMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLINTMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLINTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLINTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLINTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLINTMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLINTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLINTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLINTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLINTMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLINTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLINTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLINTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLLONGMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLLONGMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLLONGMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLLONGMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLLONGMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLLONGMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLLONGMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLLONGMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLLONGMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLLONGMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLLONGMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLOBJECTMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLOBJECTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLOBJECTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLOBJECTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLOBJECTMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLOBJECTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLOBJECTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLOBJECTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSHORTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSHORTMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSHORTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSHORTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSHORTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSHORTMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSHORTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSHORTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSHORTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(arg0)
++#define HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLVOIDMETHOD_RETURN()
++#define HOTSPOT_JNI_CALLVOIDMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLVOIDMETHODA_RETURN()
++#define HOTSPOT_JNI_CALLVOIDMETHODA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CALLVOIDMETHODV_RETURN()
++#define HOTSPOT_JNI_CALLVOIDMETHODV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_CREATEJAVAVM_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_CREATEJAVAVM_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_CREATEJAVAVM_RETURN(arg0)
++#define HOTSPOT_JNI_CREATEJAVAVM_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_DEFINECLASS_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_DEFINECLASS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_DEFINECLASS_RETURN(arg0)
++#define HOTSPOT_JNI_DEFINECLASS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_DELETEGLOBALREF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_DELETEGLOBALREF_RETURN()
++#define HOTSPOT_JNI_DELETEGLOBALREF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_DELETELOCALREF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_DELETELOCALREF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_DELETELOCALREF_RETURN()
++#define HOTSPOT_JNI_DELETELOCALREF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN()
++#define HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(arg0)
++#define HOTSPOT_JNI_DESTROYJAVAVM_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_DESTROYJAVAVM_RETURN(arg0)
++#define HOTSPOT_JNI_DESTROYJAVAVM_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(arg0)
++#define HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(arg0)
++#define HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(arg0)
++#define HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(arg0)
++#define HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(arg0)
++#define HOTSPOT_JNI_EXCEPTIONCHECK_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(arg0)
++#define HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN()
++#define HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(arg0)
++#define HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN()
++#define HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(arg0)
++#define HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(arg0)
++#define HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_FATALERROR_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_FATALERROR_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_FINDCLASS_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_FINDCLASS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_FINDCLASS_RETURN(arg0)
++#define HOTSPOT_JNI_FINDCLASS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETARRAYLENGTH_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETARRAYLENGTH_RETURN(arg0)
++#define HOTSPOT_JNI_GETARRAYLENGTH_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETBOOLEANFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETBYTEFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETBYTEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETBYTEFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETBYTEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETCHARARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETCHARARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETCHARFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETCHARFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETCHARFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETCHARFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(arg0)
++#define HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(arg0)
++#define HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(arg0)
++#define HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN(arg0)
++#define HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(arg0)
++#define HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETDOUBLEFIELD_RETURN()
++#define HOTSPOT_JNI_GETDOUBLEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETENV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETENV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETENV_RETURN(arg0)
++#define HOTSPOT_JNI_GETENV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETFIELDID_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_GETFIELDID_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETFIELDID_RETURN(arg0)
++#define HOTSPOT_JNI_GETFIELDID_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETFLOATFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETFLOATFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETFLOATFIELD_RETURN()
++#define HOTSPOT_JNI_GETFLOATFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETINTARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETINTARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETINTARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETINTFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETINTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETINTFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETINTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETJAVAVM_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETJAVAVM_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETJAVAVM_RETURN(arg0)
++#define HOTSPOT_JNI_GETJAVAVM_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETLONGARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETLONGARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETLONGFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETLONGFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETLONGFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETLONGFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETMETHODID_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_GETMETHODID_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETMETHODID_RETURN(arg0)
++#define HOTSPOT_JNI_GETMETHODID_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(arg0)
++#define HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETOBJECTCLASS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTCLASS_RETURN(arg0)
++#define HOTSPOT_JNI_GETOBJECTCLASS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETOBJECTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETOBJECTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN(arg0)
++#define HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(arg0)
++#define HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN(arg0)
++#define HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN()
++#define HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSHORTFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSHORTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSHORTFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSHORTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN()
++#define HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_GETSTATICFIELDID_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICFIELDID_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICFIELDID_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN()
++#define HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICINTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_GETSTATICMETHODID_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICMETHODID_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICMETHODID_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTRINGCHARS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGCHARS_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTRINGCHARS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTRINGLENGTH_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETSTRINGREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGREGION_RETURN()
++#define HOTSPOT_JNI_GETSTRINGREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(arg0)
++#define HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN()
++#define HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETSUPERCLASS_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_GETSUPERCLASS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETSUPERCLASS_RETURN(arg0)
++#define HOTSPOT_JNI_GETSUPERCLASS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_GETVERSION_ENTRY(arg0)
++#define HOTSPOT_JNI_GETVERSION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_GETVERSION_RETURN(arg0)
++#define HOTSPOT_JNI_GETVERSION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(arg0)
++#define HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_ISINSTANCEOF_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_ISINSTANCEOF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ISINSTANCEOF_RETURN(arg0)
++#define HOTSPOT_JNI_ISINSTANCEOF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_ISSAMEOBJECT_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_ISSAMEOBJECT_RETURN(arg0)
++#define HOTSPOT_JNI_ISSAMEOBJECT_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_MONITORENTER_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_MONITORENTER_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_MONITORENTER_RETURN(arg0)
++#define HOTSPOT_JNI_MONITORENTER_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_MONITOREXIT_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_MONITOREXIT_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_MONITOREXIT_RETURN(arg0)
++#define HOTSPOT_JNI_MONITOREXIT_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWBYTEARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWBYTEARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWBYTEARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWCHARARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWCHARARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWCHARARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWCHARARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(arg0)
++#define HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWFLOATARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWFLOATARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWFLOATARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWGLOBALREF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWGLOBALREF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWGLOBALREF_RETURN(arg0)
++#define HOTSPOT_JNI_NEWGLOBALREF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWINTARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWINTARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWINTARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWINTARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWLOCALREF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWLOCALREF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWLOCALREF_RETURN(arg0)
++#define HOTSPOT_JNI_NEWLOCALREF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWLONGARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWLONGARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWLONGARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWLONGARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECT_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_NEWOBJECT_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECT_RETURN(arg0)
++#define HOTSPOT_JNI_NEWOBJECT_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECTA_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_NEWOBJECTA_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECTA_RETURN(arg0)
++#define HOTSPOT_JNI_NEWOBJECTA_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWOBJECTARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECTV_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_NEWOBJECTV_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWOBJECTV_RETURN(arg0)
++#define HOTSPOT_JNI_NEWOBJECTV_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWSHORTARRAY_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWSHORTARRAY_RETURN(arg0)
++#define HOTSPOT_JNI_NEWSHORTARRAY_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWSTRING_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_NEWSTRING_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWSTRING_RETURN(arg0)
++#define HOTSPOT_JNI_NEWSTRING_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWSTRINGUTF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWSTRINGUTF_RETURN(arg0)
++#define HOTSPOT_JNI_NEWSTRINGUTF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(arg0)
++#define HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_POPLOCALFRAME_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_POPLOCALFRAME_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_POPLOCALFRAME_RETURN(arg0)
++#define HOTSPOT_JNI_POPLOCALFRAME_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(arg0)
++#define HOTSPOT_JNI_PUSHLOCALFRAME_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_REGISTERNATIVES_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_REGISTERNATIVES_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_REGISTERNATIVES_RETURN(arg0)
++#define HOTSPOT_JNI_REGISTERNATIVES_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN()
++#define HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN()
++#define HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN()
++#define HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN()
++#define HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN()
++#define HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETBOOLEANFIELD_RETURN()
++#define HOTSPOT_JNI_SETBOOLEANFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETBYTEFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETBYTEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETBYTEFIELD_RETURN()
++#define HOTSPOT_JNI_SETBYTEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETCHARARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETCHARARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETCHARFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETCHARFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETCHARFIELD_RETURN()
++#define HOTSPOT_JNI_SETCHARFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETDOUBLEFIELD_RETURN()
++#define HOTSPOT_JNI_SETDOUBLEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETFLOATFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_SETFLOATFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETFLOATFIELD_RETURN()
++#define HOTSPOT_JNI_SETFLOATFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETINTARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETINTARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETINTARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETINTFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETINTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETINTFIELD_RETURN()
++#define HOTSPOT_JNI_SETINTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETLONGARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETLONGARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETLONGFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETLONGFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETLONGFIELD_RETURN()
++#define HOTSPOT_JNI_SETLONGFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN()
++#define HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETOBJECTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETOBJECTFIELD_RETURN()
++#define HOTSPOT_JNI_SETOBJECTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(arg0, arg1, arg2, arg3, arg4)
++#define HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN()
++#define HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSHORTFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSHORTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSHORTFIELD_RETURN()
++#define HOTSPOT_JNI_SETSHORTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICBOOLEANFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICBOOLEANFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICINTFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICINTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN()
++#define HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_THROW_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_THROW_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_THROW_RETURN(arg0)
++#define HOTSPOT_JNI_THROW_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_THROWNEW_ENTRY(arg0, arg1, arg2)
++#define HOTSPOT_JNI_THROWNEW_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_THROWNEW_RETURN(arg0)
++#define HOTSPOT_JNI_THROWNEW_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(arg0)
++#define HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(arg0, arg1, arg2, arg3)
++#define HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(arg0)
++#define HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN_ENABLED() 0
++#define HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(arg0, arg1)
++#define HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY_ENABLED() 0
++#define HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(arg0)
++#define HOTSPOT_JNI_UNREGISTERNATIVES_RETURN_ENABLED() 0
++
++#else /* USDT2 */
++#error This file should only be included for USDT2
++#endif /* USDT2 */
++
++#else /* !defined(DTRACE_ENABLED) */
++#error This file should only be included when dtrace is not enabled
++#end /* !defined(DTRACE_ENABLED) */
++
++#endif // SHARE_VM_UTILITIES_DTRACE_USDT2_DISABLED_HPP
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/globalDefinitions.hpp 2012-07-25 15:14:34.614188609 +0100
++++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp 2012-07-25 15:27:37.299649316 +0100
+@@ -25,7 +25,9 @@
+ #ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
+ #define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
+
++#ifndef __STDC_FORMAT_MACROS
+ #define __STDC_FORMAT_MACROS
++#endif
+
+ #ifdef TARGET_COMPILER_gcc
+ # include "utilities/globalDefinitions_gcc.hpp"
+diff -Nru openjdk.orig/hotspot/src/share/vm/utilities/hashtable.cpp openjdk/hotspot/src/share/vm/utilities/hashtable.cpp
+--- openjdk.orig/hotspot/src/share/vm/utilities/hashtable.cpp 2012-06-07 19:21:17.000000000 +0100
++++ openjdk/hotspot/src/share/vm/utilities/hashtable.cpp 2012-07-25 15:27:37.299649316 +0100
+@@ -32,8 +32,10 @@
+ #include "utilities/hashtable.inline.hpp"
+
+
++#ifndef USDT2
+ HS_DTRACE_PROBE_DECL4(hs_private, hashtable__new_entry,
+ void*, unsigned int, void*, void*);
++#endif /* !USDT2 */
+
+ // This is a generic hashtable, designed to be used for the symbol
+ // and string tables.
+@@ -73,8 +75,13 @@
+
+ entry = (HashtableEntry<T>*)BasicHashtable::new_entry(hashValue);
+ entry->set_literal(obj);
++#ifndef USDT2
+ HS_DTRACE_PROBE4(hs_private, hashtable__new_entry,
+ this, hashValue, obj, entry);
++#else /* USDT2 */
++ HS_PRIVATE_HASHTABLE_NEW_ENTRY(
++ this, hashValue, (uintptr_t) obj, entry);
++#endif /* USDT2 */
+ return entry;
+ }
+
diff --git a/patches/hotspot/zero/7116189-setnativethreadname.patch b/patches/hotspot/zero/7116189-setnativethreadname.patch
new file mode 100644
index 0000000..61ad857
--- /dev/null
+++ b/patches/hotspot/zero/7116189-setnativethreadname.patch
@@ -0,0 +1,67 @@
+# HG changeset patch
+# User phh
+# Date 1322576462 18000
+# Node ID 242b4e0e6f739e6225c4a95e4cb779c881d032f9
+# Parent c17bc65648de3d12a0c5aa8d84b509b1ddfe1a4a
+7116189: Export JVM_SetNativeThreadName from Hotspot
+Summary: Added JVM_SetNativeThreadName to linker mapfiles on Solaris and Linux.
+Reviewed-by: dcubed, dholmes
+Contributed-by: michael.x.mcmahon@oracle.com
+
+diff --git a/make/linux/makefiles/mapfile-vers-debug b/make/linux/makefiles/mapfile-vers-debug
+--- openjdk/hotspot/make/linux/makefiles/mapfile-vers-debug
++++ openjdk/hotspot/make/linux/makefiles/mapfile-vers-debug
+@@ -1,7 +1,3 @@
+-#
+-# @(#)mapfile-vers-debug 1.18 07/10/25 16:47:35
+-#
+-
+ #
+ # Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -221,6 +217,7 @@
+ JVM_SetArrayElement;
+ JVM_SetClassSigners;
+ JVM_SetLength;
++ JVM_SetNativeThreadName;
+ JVM_SetPrimitiveArrayElement;
+ JVM_SetProtectionDomain;
+ JVM_SetSockOpt;
+diff --git a/make/linux/makefiles/mapfile-vers-product b/make/linux/makefiles/mapfile-vers-product
+--- openjdk/hotspot/make/linux/makefiles/mapfile-vers-product
++++ openjdk/hotspot/make/linux/makefiles/mapfile-vers-product
+@@ -1,7 +1,3 @@
+-#
+-# @(#)mapfile-vers-product 1.19 08/02/12 10:56:37
+-#
+-
+ #
+ # Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -221,6 +217,7 @@
+ JVM_SetArrayElement;
+ JVM_SetClassSigners;
+ JVM_SetLength;
++ JVM_SetNativeThreadName;
+ JVM_SetPrimitiveArrayElement;
+ JVM_SetProtectionDomain;
+ JVM_SetSockOpt;
+diff --git a/make/solaris/makefiles/mapfile-vers b/make/solaris/makefiles/mapfile-vers
+--- openjdk/hotspot/make/solaris/makefiles/mapfile-vers
++++ openjdk/hotspot/make/solaris/makefiles/mapfile-vers
+@@ -1,7 +1,3 @@
+-#
+-# @(#)mapfile-vers 1.32 07/10/25 16:47:36
+-#
+-
+ #
+ # Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+@@ -221,6 +217,7 @@
+ JVM_SetArrayElement;
+ JVM_SetClassSigners;
+ JVM_SetLength;
++ JVM_SetNativeThreadName;
+ JVM_SetPrimitiveArrayElement;
+ JVM_SetProtectionDomain;
+ JVM_SetSockOpt;
diff --git a/patches/hotspot/zero/7175133-string_offset.patch b/patches/hotspot/zero/7175133-string_offset.patch
new file mode 100644
index 0000000..8bd953a
--- /dev/null
+++ b/patches/hotspot/zero/7175133-string_offset.patch
@@ -0,0 +1,48 @@
+# HG changeset patch
+# User minqi
+# Date 1340404530 25200
+# Node ID cfb2ea9dfefdae6d8cd7c1723cf0f1841f6686fe
+# Parent 571bc10e2a375631a8f685b5f218d323f9bdf93b
+7175133: jinfo failed to get system properties after 6924259
+Summary: String offset and count fields as fix of 6924259 were removed, and become optional. SA still use offset and count fields to read String contents and failed. Fix if they exist, use them other then use value field only to read, this keeps consistent with the changes in 6924259.
+Reviewed-by: dholmes, mikael
+Contributed-by: yumin.qi@oracle.com
+
+diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java
+--- openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java
++++ openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -141,18 +141,19 @@
+ public static String stringOopToString(Oop stringOop) {
+ if (offsetField == null) {
+ InstanceKlass k = (InstanceKlass) stringOop.getKlass();
+- offsetField = (IntField) k.findField("offset", "I");
+- countField = (IntField) k.findField("count", "I");
++ offsetField = (IntField) k.findField("offset", "I"); // optional
++ countField = (IntField) k.findField("count", "I"); // optional
+ valueField = (OopField) k.findField("value", "[C");
+ if (Assert.ASSERTS_ENABLED) {
+- Assert.that(offsetField != null &&
+- countField != null &&
+- valueField != null, "must find all java.lang.String fields");
++ Assert.that(valueField != null, "Field \'value\' of java.lang.String not found");
+ }
+ }
+- return charArrayToString((TypeArray) valueField.getValue(stringOop),
+- offsetField.getValue(stringOop),
+- countField.getValue(stringOop));
++ if (offsetField != null && countField != null) {
++ return charArrayToString((TypeArray) valueField.getValue(stringOop),
++ offsetField.getValue(stringOop),
++ countField.getValue(stringOop));
++ }
++ return charArrayToString((TypeArray) valueField.getValue(stringOop));
+ }
+
+ public static String stringOopToEscapedString(Oop stringOop) {
diff --git a/patches/hotspot/zero/revert-7017193.patch b/patches/hotspot/zero/revert-7017193.patch
new file mode 100644
index 0000000..7511b31
--- /dev/null
+++ b/patches/hotspot/zero/revert-7017193.patch
@@ -0,0 +1,136 @@
+diff -Nru openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp openjdk/hotspot/src/os/linux/vm/os_linux.cpp
+--- openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp 2013-02-15 00:04:42.000000000 +0000
++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2013-03-11 20:15:01.080257099 +0000
+@@ -2788,39 +2788,47 @@
+ // writing thread stacks don't use growable mappings (i.e. those
+ // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
+ // only applies to the main thread.
+-
+-static
+-bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) {
+-
+- char buf[128];
+- int fd, sz;
+-
+- if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) {
++static bool
++get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
++{
++ FILE *f = fopen("/proc/self/maps", "r");
++ if (f == NULL)
+ return false;
+- }
+
+- const char kw[] = "[stack]";
+- const int kwlen = sizeof(kw)-1;
+-
+- // Address part of /proc/self/maps couldn't be more than 128 bytes
+- while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) {
+- if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) {
+- // Extract addresses
+- if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
+- uintptr_t sp = (uintptr_t) __builtin_frame_address(0);
+- if (sp >= *bottom && sp <= *top) {
+- ::close(fd);
+- return true;
+- }
++ while (!feof(f)) {
++ size_t dummy;
++ char *str = NULL;
++ ssize_t len = getline(&str, &dummy, f);
++ if (len == -1) {
++ fclose(f);
++ if (str != NULL)
++ free(str);
++ return false;
++ }
++
++ if (len > 0 && str[len-1] == '\n') {
++ str[len-1] = 0;
++ len--;
++ }
++
++ static const char *stack_str = "[stack]";
++ if (len > (ssize_t)strlen(stack_str)
++ && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
++ if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
++ uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
++ if (sp >= *bottom && sp <= *top) {
++ free(str);
++ fclose(f);
++ return true;
+ }
+- }
++ }
++ }
++ free(str);
+ }
+-
+- ::close(fd);
++ fclose(f);
+ return false;
+ }
+
+-
+ // If the (growable) stack mapping already extends beyond the point
+ // where we're going to put our guard pages, truncate the mapping at
+ // that point by munmap()ping it. This ensures that when we later
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.cpp openjdk/hotspot/src/share/vm/runtime/os.cpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/os.cpp 2013-02-15 00:04:42.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/os.cpp 2013-03-11 20:15:01.080257099 +0000
+@@ -1306,41 +1306,3 @@
+ }
+ return result;
+ }
+-
+-// Read file line by line, if line is longer than bsize,
+-// skip rest of line.
+-int os::get_line_chars(int fd, char* buf, const size_t bsize){
+- size_t sz, i = 0;
+-
+- // read until EOF, EOL or buf is full
+- while ((sz = (int) read(fd, &buf[i], 1)) == 1 && i < (bsize-2) && buf[i] != '\n') {
+- ++i;
+- }
+-
+- if (buf[i] == '\n') {
+- // EOL reached so ignore EOL character and return
+-
+- buf[i] = 0;
+- return (int) i;
+- }
+-
+- buf[i+1] = 0;
+-
+- if (sz != 1) {
+- // EOF reached. if we read chars before EOF return them and
+- // return EOF on next call otherwise return EOF
+-
+- return (i == 0) ? -1 : (int) i;
+- }
+-
+- // line is longer than size of buf, skip to EOL
+- char ch;
+- while (read(fd, &ch, 1) == 1 && ch != '\n') {
+- // Do nothing
+- }
+-
+- // return initial part of line that fits in buf.
+- // If we reached EOF, it will be returned on next call.
+-
+- return (int) i;
+-}
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.hpp openjdk/hotspot/src/share/vm/runtime/os.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/os.hpp 2013-02-15 00:04:42.000000000 +0000
++++ openjdk/hotspot/src/share/vm/runtime/os.hpp 2013-03-11 20:15:16.008497745 +0000
+@@ -661,10 +661,6 @@
+ // Hook for os specific jvm options that we don't want to abort on seeing
+ static bool obsolete_option(const JavaVMOption *option);
+
+- // Read file line by line. If line is longer than bsize,
+- // rest of line is skipped. Returns number of bytes read or -1 on EOF
+- static int get_line_chars(int fd, char *buf, const size_t bsize);
+-
+ // Platform dependent stuff
+ #ifdef TARGET_OS_FAMILY_linux
+ # include "os_linux.hpp"
diff --git a/patches/hotspot/zero/revert_arm_debug.patch b/patches/hotspot/zero/revert_arm_debug.patch
new file mode 100644
index 0000000..a9e4ca9
--- /dev/null
+++ b/patches/hotspot/zero/revert_arm_debug.patch
@@ -0,0 +1,55 @@
+# HG changeset patch
+# User aph
+# Date 1331812639 14400
+# Node ID c1d02b230f8f510a81f90af5aecd987ae682ebf2
+# Parent 61248c69e562f003071f4fd8c814b62b25d5fe94
+Add patches/arm-debug.patch from IcedTea 6
+
+diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp
+--- openjdk/hotspot/src/share/vm/utilities/vmError.cpp
++++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp
+@@ -248,19 +248,6 @@
+ return buf;
+ }
+
+-#ifdef PRODUCT
+-extern "C" void ps() {
+- fdStream out(defaultStream::output_fd());
+- JavaThread* thread = JavaThread::active();
+- char *buf = new char[1024*1024];
+- VMError err(thread, "", 0, "", "");
+-
+- err.print_stack_trace(&out, thread, buf, 1024*1024, true);
+-
+- delete[] buf;
+-}
+-#endif // PRODUCT
+-
+ void VMError::print_stack_trace(outputStream* st, JavaThread* jt,
+ char* buf, int buflen, bool verbose) {
+ #ifdef ZERO
+diff --git a/src/share/vm/utilities/vmError.hpp b/src/share/vm/utilities/vmError.hpp
+--- openjdk/hotspot/src/share/vm/utilities/vmError.hpp
++++ openjdk/hotspot/src/share/vm/utilities/vmError.hpp
+@@ -30,10 +30,6 @@
+
+ class VM_ReportJavaOutOfMemory;
+
+-#ifdef PRODUCT
+-extern "C" void ps();
+-#endif // PRODUCT
+-
+ class VMError : public StackObj {
+ friend class VM_ReportJavaOutOfMemory;
+
+@@ -97,10 +101,6 @@
+ const char* detail_msg() const { return _detail_msg; }
+ bool should_report_bug(unsigned int id) { return id != oom_error; }
+
+-#ifdef PRODUCT
+- friend void ps();
+-#endif // PRODUCT
+-
+ public:
+ // Constructor for crashes
+ VMError(Thread* thread, unsigned int sig, address pc, void* siginfo,