publicclass Main { publicstaticvoid main(String[] args) throws Exception { if (!isDalvik) { // This test is ART-specific. Just fake the expected output.
System.out.println("JNI_OnLoad called"); return;
}
System.loadLibrary(args[0]); if (!hasJit()) { return;
}
testValueOfArg();
testValueOfConst();
}
publicstaticvoid testValueOfArg() throws Exception { final VolatileFlag start_end = new VolatileFlag(); Thread t = newThread() {
@Override publicvoid run() { try { Class<?> integerCacheClass = Class.forName("java.lang.Integer$IntegerCache");
Field cacheField = integerCacheClass.getDeclaredField("cache");
cacheField.setAccessible(true);
// Let the main thread know that everything is set up. synchronized (start_end) {
start_end.notify();
}
while (!start_end.flag) {
cache[0] = alternativeZero;
cache[0] = originalZero;
}
} catch (Throwable t) { thrownew Error(t);
}
}
}; synchronized (start_end) {
t.start();
start_end.wait(); // Wait for the thread to start.
} // Previously, this may have used an invalid IntegerValueOfInfo (because of seeing // the `alternativeZero` which is not in the boot image) when asked to emit code after // using a valid info (using `originalZero`) when requesting locations.
ensureJitCompiled(Main.class, "getAsInteger");
start_end.flag = true;
t.join();
Runtime.getRuntime().gc(); // Collect the `alternativeZero`.
// If `getAsInteger()` was miscompiled, it shall try to retrieve an Integer reference // from a collected array (low = 0, high = 0 means that this happens only for value 0), // reading from a bogus location. Depending on the GC type, this bogus memory access may // yield SIGSEGV or `null` or even a valid reference.
Integer new0 = getAsInteger(0); int value = (int) new0;
if (value != 0) { thrownew Error("value is " + value);
}
}
publicstaticvoid testValueOfConst() throws Exception { Class<?> integerCacheClass = Class.forName("java.lang.Integer$IntegerCache");
Field cacheField = integerCacheClass.getDeclaredField("cache");
cacheField.setAccessible(true);
Field lowField = integerCacheClass.getDeclaredField("low");
lowField.setAccessible(true);
// This used to hit // DCHECK(boxed != nullptr && // Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(boxed)); // when compiling the intrinsic.
ensureJitCompiled(Main.class, "get42AsInteger");
// If the DCHECK() was removed, MterpInvokeVirtualQuick() used to crash here. // (Note: Our fault handler on x86-64 then also crashed.) int value = (int) new42;
if (value != (int) old42) { thrownew Error("value is " + value);
}
}
privatestaticclass VolatileFlag { publicvolatileboolean flag = false;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.