Skip to content

Commit 574263a

Browse files
committedOct 24, 2019
8232613: Move Object.registerNatives into HotSpot
Reviewed-by: dholmes, adinn, coleenp, lfoltan, mchung
1 parent 68e5c40 commit 574263a

File tree

13 files changed

+312
-136
lines changed

13 files changed

+312
-136
lines changed
 

‎src/hotspot/share/classfile/javaClasses.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ InjectedField JavaClasses::_injected_fields[] = {
8787
ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD)
8888
};
8989

90+
// Register native methods of Object
91+
void java_lang_Object::register_natives(TRAPS) {
92+
InstanceKlass* obj = SystemDictionary::Object_klass();
93+
Method::register_native(obj, vmSymbols::hashCode_name(),
94+
vmSymbols::void_int_signature(), (address) &JVM_IHashCode, CHECK);
95+
Method::register_native(obj, vmSymbols::wait_name(),
96+
vmSymbols::long_void_signature(), (address) &JVM_MonitorWait, CHECK);
97+
Method::register_native(obj, vmSymbols::notify_name(),
98+
vmSymbols::void_method_signature(), (address) &JVM_MonitorNotify, CHECK);
99+
Method::register_native(obj, vmSymbols::notifyAll_name(),
100+
vmSymbols::void_method_signature(), (address) &JVM_MonitorNotifyAll, CHECK);
101+
Method::register_native(obj, vmSymbols::clone_name(),
102+
vmSymbols::void_object_signature(), (address) &JVM_Clone, THREAD);
103+
}
104+
90105
int JavaClasses::compute_injected_offset(InjectedFieldID id) {
91106
return _injected_fields[id].compute_offset();
92107
}

‎src/hotspot/share/classfile/javaClasses.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@
8888
BASIC_JAVA_CLASSES_DO_PART1(f) \
8989
BASIC_JAVA_CLASSES_DO_PART2(f)
9090

91+
// Interface to java.lang.Object objects
92+
93+
class java_lang_Object : AllStatic {
94+
public:
95+
static void register_natives(TRAPS);
96+
};
97+
9198
// Interface to java.lang.String objects
9299

93100
class java_lang_String : AllStatic {

‎src/hotspot/share/classfile/systemDictionary.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1972,6 +1972,10 @@ void SystemDictionary::resolve_well_known_classes(TRAPS) {
19721972
resolve_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
19731973
}
19741974

1975+
assert(WK_KLASS(Object_klass) != NULL, "well-known classes should now be initialized");
1976+
1977+
java_lang_Object::register_natives(CHECK);
1978+
19751979
// Calculate offsets for String and Class classes since they are loaded and
19761980
// can be used after this point.
19771981
java_lang_String::compute_offsets();

‎src/hotspot/share/classfile/systemDictionary.hpp

-17
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ class GCTimer;
219219
\
220220
/*end*/
221221

222-
223222
class SystemDictionary : AllStatic {
224223
friend class BootstrapInfo;
225224
friend class VMStructs;
@@ -383,7 +382,6 @@ class SystemDictionary : AllStatic {
383382
int limit = (int)end_id + 1;
384383
resolve_wk_klasses_until((WKID) limit, start_id, THREAD);
385384
}
386-
387385
public:
388386
#define WK_KLASS_DECLARE(name, symbol) \
389387
static InstanceKlass* name() { return check_klass(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); } \
@@ -628,21 +626,6 @@ class SystemDictionary : AllStatic {
628626
// Basic find on classes in the midst of being loaded
629627
static Symbol* find_placeholder(Symbol* name, ClassLoaderData* loader_data);
630628

631-
// Add a placeholder for a class being loaded
632-
static void add_placeholder(int index,
633-
Symbol* class_name,
634-
ClassLoaderData* loader_data);
635-
static void remove_placeholder(int index,
636-
Symbol* class_name,
637-
ClassLoaderData* loader_data);
638-
639-
// Performs cleanups after resolve_super_or_fail. This typically needs
640-
// to be called on failure.
641-
// Won't throw, but can block.
642-
static void resolution_cleanups(Symbol* class_name,
643-
ClassLoaderData* loader_data,
644-
TRAPS);
645-
646629
// Resolve well-known classes so they can be used like SystemDictionary::String_klass()
647630
static void resolve_well_known_classes(TRAPS);
648631

‎src/hotspot/share/oops/method.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "precompiled.hpp"
2626
#include "classfile/classLoaderDataGraph.hpp"
2727
#include "classfile/metadataOnStackMark.hpp"
28+
#include "classfile/symbolTable.hpp"
2829
#include "classfile/systemDictionary.hpp"
2930
#include "code/codeCache.hpp"
3031
#include "code/debugInfoRec.hpp"
@@ -378,7 +379,83 @@ void Method::set_itable_index(int index) {
378379
assert(valid_itable_index(), "");
379380
}
380381

382+
// The RegisterNatives call being attempted tried to register with a method that
383+
// is not native. Ask JVM TI what prefixes have been specified. Then check
384+
// to see if the native method is now wrapped with the prefixes. See the
385+
// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
386+
static Method* find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS) {
387+
#if INCLUDE_JVMTI
388+
ResourceMark rm(THREAD);
389+
Method* method;
390+
int name_len = name->utf8_length();
391+
char* name_str = name->as_utf8();
392+
int prefix_count;
393+
char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
394+
for (int i = 0; i < prefix_count; i++) {
395+
char* prefix = prefixes[i];
396+
int prefix_len = (int)strlen(prefix);
397+
398+
// try adding this prefix to the method name and see if it matches another method name
399+
int trial_len = name_len + prefix_len;
400+
char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
401+
strcpy(trial_name_str, prefix);
402+
strcat(trial_name_str, name_str);
403+
TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
404+
if (trial_name == NULL) {
405+
continue; // no such symbol, so this prefix wasn't used, try the next prefix
406+
}
407+
method = k->lookup_method(trial_name, signature);
408+
if (method == NULL) {
409+
continue; // signature doesn't match, try the next prefix
410+
}
411+
if (method->is_native()) {
412+
method->set_is_prefixed_native();
413+
return method; // wahoo, we found a prefixed version of the method, return it
414+
}
415+
// found as non-native, so prefix is good, add it, probably just need more prefixes
416+
name_len = trial_len;
417+
name_str = trial_name_str;
418+
}
419+
#endif // INCLUDE_JVMTI
420+
return NULL; // not found
421+
}
422+
423+
bool Method::register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS) {
424+
Method* method = k->lookup_method(name, signature);
425+
if (method == NULL) {
426+
ResourceMark rm(THREAD);
427+
stringStream st;
428+
st.print("Method '");
429+
print_external_name(&st, k, name, signature);
430+
st.print("' name or signature does not match");
431+
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
432+
}
433+
if (!method->is_native()) {
434+
// trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
435+
method = find_prefixed_native(k, name, signature, THREAD);
436+
if (method == NULL) {
437+
ResourceMark rm(THREAD);
438+
stringStream st;
439+
st.print("Method '");
440+
print_external_name(&st, k, name, signature);
441+
st.print("' is not declared as native");
442+
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
443+
}
444+
}
381445

446+
if (entry != NULL) {
447+
method->set_native_function(entry, native_bind_event_is_interesting);
448+
} else {
449+
method->clear_native_function();
450+
}
451+
if (PrintJNIResolving) {
452+
ResourceMark rm(THREAD);
453+
tty->print_cr("[Registering JNI native method %s.%s]",
454+
method->method_holder()->external_name(),
455+
method->name()->as_C_string());
456+
}
457+
return true;
458+
}
382459

383460
bool Method::was_executed_more_than(int n) {
384461
// Invocation counter is reset when the Method* is compiled.

‎src/hotspot/share/oops/method.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,12 @@ class Method : public Metadata {
346346
// InterpreterRuntime::exception_handler_for_exception.
347347
static int fast_exception_handler_bci_for(const methodHandle& mh, Klass* ex_klass, int throw_bci, TRAPS);
348348

349+
static bool register_native(Klass* k,
350+
Symbol* name,
351+
Symbol* signature,
352+
address entry,
353+
TRAPS);
354+
349355
// method data access
350356
MethodData* method_data() const {
351357
return _method_data;

‎src/hotspot/share/prims/jni.cpp

+2-85
Original file line numberDiff line numberDiff line change
@@ -2909,89 +2909,6 @@ DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double
29092909
HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
29102910

29112911

2912-
//
2913-
// Interception of natives
2914-
//
2915-
2916-
// The RegisterNatives call being attempted tried to register with a method that
2917-
// is not native. Ask JVM TI what prefixes have been specified. Then check
2918-
// to see if the native method is now wrapped with the prefixes. See the
2919-
// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
2920-
static Method* find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS) {
2921-
#if INCLUDE_JVMTI
2922-
ResourceMark rm(THREAD);
2923-
Method* method;
2924-
int name_len = name->utf8_length();
2925-
char* name_str = name->as_utf8();
2926-
int prefix_count;
2927-
char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
2928-
for (int i = 0; i < prefix_count; i++) {
2929-
char* prefix = prefixes[i];
2930-
int prefix_len = (int)strlen(prefix);
2931-
2932-
// try adding this prefix to the method name and see if it matches another method name
2933-
int trial_len = name_len + prefix_len;
2934-
char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
2935-
strcpy(trial_name_str, prefix);
2936-
strcat(trial_name_str, name_str);
2937-
TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
2938-
if (trial_name == NULL) {
2939-
continue; // no such symbol, so this prefix wasn't used, try the next prefix
2940-
}
2941-
method = k->lookup_method(trial_name, signature);
2942-
if (method == NULL) {
2943-
continue; // signature doesn't match, try the next prefix
2944-
}
2945-
if (method->is_native()) {
2946-
method->set_is_prefixed_native();
2947-
return method; // wahoo, we found a prefixed version of the method, return it
2948-
}
2949-
// found as non-native, so prefix is good, add it, probably just need more prefixes
2950-
name_len = trial_len;
2951-
name_str = trial_name_str;
2952-
}
2953-
#endif // INCLUDE_JVMTI
2954-
return NULL; // not found
2955-
}
2956-
2957-
static bool register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS) {
2958-
Method* method = k->lookup_method(name, signature);
2959-
if (method == NULL) {
2960-
ResourceMark rm;
2961-
stringStream st;
2962-
st.print("Method '");
2963-
Method::print_external_name(&st, k, name, signature);
2964-
st.print("' name or signature does not match");
2965-
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
2966-
}
2967-
if (!method->is_native()) {
2968-
// trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
2969-
method = find_prefixed_native(k, name, signature, THREAD);
2970-
if (method == NULL) {
2971-
ResourceMark rm;
2972-
stringStream st;
2973-
st.print("Method '");
2974-
Method::print_external_name(&st, k, name, signature);
2975-
st.print("' is not declared as native");
2976-
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
2977-
}
2978-
}
2979-
2980-
if (entry != NULL) {
2981-
method->set_native_function(entry,
2982-
Method::native_bind_event_is_interesting);
2983-
} else {
2984-
method->clear_native_function();
2985-
}
2986-
if (PrintJNIResolving) {
2987-
ResourceMark rm(THREAD);
2988-
tty->print_cr("[Registering JNI native method %s.%s]",
2989-
method->method_holder()->external_name(),
2990-
method->name()->as_C_string());
2991-
}
2992-
return true;
2993-
}
2994-
29952912
DT_RETURN_MARK_DECL(RegisterNatives, jint
29962913
, HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
29972914

@@ -3024,8 +2941,8 @@ JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
30242941
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
30252942
}
30262943

3027-
bool res = register_native(k, name, signature,
3028-
(address) methods[index].fnPtr, THREAD);
2944+
bool res = Method::register_native(k, name, signature,
2945+
(address) methods[index].fnPtr, THREAD);
30292946
if (!res) {
30302947
ret = -1;
30312948
break;

‎src/java.base/share/classes/java/lang/Object.java

-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@
3838
*/
3939
public class Object {
4040

41-
private static native void registerNatives();
42-
static {
43-
registerNatives();
44-
}
45-
4641
/**
4742
* Constructs a new object.
4843
*/

‎src/java.base/share/native/libjava/Object.c

-15
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,6 @@
3939

4040
#include "java_lang_Object.h"
4141

42-
static JNINativeMethod methods[] = {
43-
{"hashCode", "()I", (void *)&JVM_IHashCode},
44-
{"wait", "(J)V", (void *)&JVM_MonitorWait},
45-
{"notify", "()V", (void *)&JVM_MonitorNotify},
46-
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
47-
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
48-
};
49-
50-
JNIEXPORT void JNICALL
51-
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
52-
{
53-
(*env)->RegisterNatives(env, cls,
54-
methods, sizeof(methods)/sizeof(methods[0]));
55-
}
56-
5742
JNIEXPORT jclass JNICALL
5843
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
5944
{

‎test/hotspot/jtreg/compiler/dependencies/MonomorphicObjectCall/java.base/java/lang/Object.java

-5
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ public class Object {
3434
@HotSpotIntrinsicCandidate
3535
public Object() {}
3636

37-
private static native void registerNatives();
38-
static {
39-
registerNatives();
40-
}
41-
4237
@HotSpotIntrinsicCandidate
4338
public final native Class<?> getClass();
4439

‎test/hotspot/jtreg/runtime/8024804/RegisterNatives.java

+24-4
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,27 @@
2323

2424
/*
2525
* @test
26-
* @bug 8024804
27-
* @bug 8028741
26+
* @bug 8024804 8028741 8232613
2827
* @summary interface method resolution should skip finding j.l.Object's registerNatives() and succeed in selecting class B's registerNatives()
2928
* @run main RegisterNatives
3029
*/
3130
public class RegisterNatives {
32-
interface I { void registerNatives(); }
31+
interface I {
32+
void registerNatives();
33+
}
34+
3335
interface J extends I {}
34-
static class B implements J { public void registerNatives() { System.out.println("B"); } }
36+
37+
interface K {
38+
default public void registerNatives() { System.out.println("K"); }
39+
}
40+
41+
static class B implements J {
42+
public void registerNatives() { System.out.println("B"); }
43+
}
44+
45+
static class C implements K {}
46+
3547
public static void main(String... args) {
3648
System.out.println("Regression test for JDK-8024804, crash when InterfaceMethodref resolves to Object.registerNatives\n");
3749
J val = new B();
@@ -42,6 +54,14 @@ public static void main(String... args) {
4254
e.printStackTrace();
4355
throw e;
4456
}
57+
C cval = new C();
58+
try {
59+
cval.registerNatives();
60+
} catch (IllegalAccessError e) {
61+
System.out.println("TEST FAILS - a default method named registerNatives should no longer be masked by removed Object.registerNatives\n");
62+
e.printStackTrace();
63+
throw e;
64+
}
4565
System.out.println("TEST PASSES - no IAE resulted\n");
4666
}
4767
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8232613
27+
* @summary Ensure Object natives stay registered after redefinition
28+
* @library /test/lib
29+
* @modules java.base/jdk.internal.misc
30+
* java.base/jdk.internal.org.objectweb.asm
31+
* java.compiler
32+
* java.instrument
33+
* jdk.jartool/sun.tools.jar
34+
* @run main RedefineObject buildagent
35+
* @run main/othervm -javaagent:redefineagent.jar RedefineObject
36+
*/
37+
38+
import static jdk.test.lib.Asserts.assertTrue;
39+
import java.io.FileNotFoundException;
40+
import java.io.PrintWriter;
41+
import java.lang.RuntimeException;
42+
import java.lang.instrument.ClassFileTransformer;
43+
import java.lang.instrument.IllegalClassFormatException;
44+
import java.lang.instrument.Instrumentation;
45+
import java.lang.instrument.UnmodifiableClassException;
46+
import java.security.ProtectionDomain;
47+
import java.util.Arrays;
48+
49+
import jdk.internal.org.objectweb.asm.ClassReader;
50+
import jdk.internal.org.objectweb.asm.ClassVisitor;
51+
import jdk.internal.org.objectweb.asm.ClassWriter;
52+
53+
import static jdk.internal.org.objectweb.asm.Opcodes.ASM6;
54+
import static jdk.internal.org.objectweb.asm.Opcodes.V1_8;
55+
56+
public class RedefineObject {
57+
58+
static Instrumentation inst;
59+
60+
public static void premain(String agentArgs, Instrumentation inst) {
61+
RedefineObject.inst = inst;
62+
}
63+
64+
static class Transformer implements ClassFileTransformer {
65+
66+
public byte[] asm(ClassLoader loader, String className,
67+
Class<?> classBeingRedefined,
68+
ProtectionDomain protectionDomain, byte[] classfileBuffer)
69+
throws IllegalClassFormatException {
70+
ClassWriter cw = new ClassWriter(0);
71+
// Force an older ASM to force a bytecode update
72+
ClassVisitor cv = new DummyClassVisitor(ASM6, cw) { };
73+
ClassReader cr = new ClassReader(classfileBuffer);
74+
cr.accept(cv, 0);
75+
byte[] bytes = cw.toByteArray();
76+
return bytes;
77+
}
78+
79+
public class DummyClassVisitor extends ClassVisitor {
80+
81+
public DummyClassVisitor(int api, ClassVisitor cv) {
82+
super(api, cv);
83+
}
84+
85+
public void visit(
86+
final int version,
87+
final int access,
88+
final String name,
89+
final String signature,
90+
final String superName,
91+
final String[] interfaces) {
92+
// Artificially lower to JDK 8 version to force a redefine
93+
cv.visit(V1_8, access, name, signature, superName, interfaces);
94+
}
95+
}
96+
97+
@Override public byte[] transform(ClassLoader loader, String className,
98+
Class<?> classBeingRedefined,
99+
ProtectionDomain protectionDomain, byte[] classfileBuffer)
100+
throws IllegalClassFormatException {
101+
102+
if (className.contains("java/lang/Object")) {
103+
try {
104+
// Here we remove and re-add the dummy fields. This shuffles the constant pool
105+
return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
106+
} catch (Throwable e) {
107+
// The retransform native code that called this method does not propagate
108+
// exceptions. Instead of getting an uninformative generic error, catch
109+
// problems here and print it, then exit.
110+
e.printStackTrace();
111+
System.exit(1);
112+
}
113+
}
114+
return null;
115+
}
116+
}
117+
118+
private static void buildAgent() {
119+
try {
120+
ClassFileInstaller.main("RedefineObject");
121+
} catch (Exception e) {
122+
throw new RuntimeException("Could not write agent classfile", e);
123+
}
124+
125+
try {
126+
PrintWriter pw = new PrintWriter("MANIFEST.MF");
127+
pw.println("Premain-Class: RedefineObject");
128+
pw.println("Agent-Class: RedefineObject");
129+
pw.println("Can-Retransform-Classes: true");
130+
pw.close();
131+
} catch (FileNotFoundException e) {
132+
throw new RuntimeException("Could not write manifest file for the agent", e);
133+
}
134+
135+
sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
136+
if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineObject.class" })) {
137+
throw new RuntimeException("Could not write the agent jar file");
138+
}
139+
}
140+
141+
public static void main(String[] args) throws Exception {
142+
143+
int objHash = System.identityHashCode(Object.class);
144+
System.out.println("Object hashCode: " + objHash);
145+
if (args.length == 1 && args[0].equals("buildagent")) {
146+
buildAgent();
147+
return;
148+
}
149+
150+
if (inst == null) {
151+
throw new RuntimeException("Instrumentation object was null");
152+
}
153+
154+
try {
155+
inst.addTransformer(new RedefineObject.Transformer(), true);
156+
inst.retransformClasses(Object.class);
157+
} catch (UnmodifiableClassException e) {
158+
throw new RuntimeException(e);
159+
}
160+
161+
// Exercise native methods on Object after transform
162+
Object b = new Object();
163+
b.hashCode();
164+
165+
C c = new C();
166+
assertTrue(c.hashCode() != c.clone().hashCode() || c != c.clone());
167+
assertTrue(c.clone() instanceof C);
168+
c = (C)c.clone(); // native method on new Object
169+
}
170+
171+
private static class C implements Cloneable {
172+
@Override
173+
protected Object clone() throws CloneNotSupportedException {
174+
return super.clone();
175+
}
176+
}
177+
}

‎test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI04/bi04t002/newclass02/java.base/java/lang/Object.java

-5
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@
3737
*/
3838
public class Object {
3939

40-
private static native void registerNatives();
41-
static {
42-
registerNatives();
43-
}
44-
4540
/**
4641
* Returns the runtime class of an object. That <tt>Class</tt>
4742
* object is the object that is locked by <tt>static synchronized</tt>

0 commit comments

Comments
 (0)
Please sign in to comment.