From 0dbe225049f6bb63b772759935306c088bdc7921 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Sat, 25 Jan 2014 10:11:19 -0700 Subject: [PATCH 1/4] add sublimetext files to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8800bb0b0c..84786ef46a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ bin /distrib *.pdb *.swp +/*.sublime-* From 68bb65cb91f971c2415b753dc1443ab7f6b86667 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 30 Jan 2014 17:34:59 -0700 Subject: [PATCH 2/4] improve c++ test harness --- unittest/codegen/assembler-test.cpp | 44 +++++---------- unittest/codegen/registers-test.cpp | 37 +++++------- unittest/test-harness.h | 65 +++++++++++++-------- unittest/util/arg-parser-test.cpp | 87 +++++++++++++---------------- 4 files changed, 113 insertions(+), 120 deletions(-) diff --git a/unittest/codegen/assembler-test.cpp b/unittest/codegen/assembler-test.cpp index 2109e30a63..deab7695c8 100644 --- a/unittest/codegen/assembler-test.cpp +++ b/unittest/codegen/assembler-test.cpp @@ -62,35 +62,21 @@ public: }; -class BasicAssemblerTest : public Test { -public: - BasicAssemblerTest(): - Test("BasicAssembler") - {} +TEST(BasicAssembler) { + BasicEnv env; + Asm a(env); +} - virtual void run() { - BasicEnv env; - Asm a(env); +TEST(ArchitecturePlan) { + BasicEnv env; + + for(int op = (int)lir::Call; op < (int)lir::AlignedJump; op++) { + bool thunk; + OperandMask mask; + env.arch->plan((lir::UnaryOperation)op, vm::TargetBytesPerWord, mask, &thunk); + assertFalse(thunk); + assertNotEqual(static_cast(0), mask.typeMask); + assertNotEqual(static_cast(0), mask.registerMask); } -} basicAssemblerTest; -class ArchitecturePlanTest : public Test { -public: - ArchitecturePlanTest(): - Test("ArchitecturePlan") - {} - - virtual void run() { - BasicEnv env; - - for(int op = (int)lir::Call; op < (int)lir::AlignedJump; op++) { - bool thunk; - OperandMask mask; - env.arch->plan((lir::UnaryOperation)op, vm::TargetBytesPerWord, mask, &thunk); - assertFalse(thunk); - assertNotEqual(static_cast(0), mask.typeMask); - assertNotEqual(static_cast(0), mask.registerMask); - } - - } -} architecturePlanTest; +} diff --git a/unittest/codegen/registers-test.cpp b/unittest/codegen/registers-test.cpp index f9d253c4c4..8502ee973a 100644 --- a/unittest/codegen/registers-test.cpp +++ b/unittest/codegen/registers-test.cpp @@ -19,26 +19,19 @@ using namespace avian::codegen; using namespace vm; -class RegisterIteratorTest : public Test { -public: - RegisterIteratorTest(): - Test("RegisterIterator") - {} +TEST(RegisterIterator) { + RegisterMask regs(0x55); + assertEqual(0, regs.start); + assertEqual(7, regs.limit); - virtual void run() { - RegisterMask regs(0x55); - assertEqual(0, regs.start); - assertEqual(7, regs.limit); - - RegisterIterator it(regs); - assertTrue(it.hasNext()); - assertEqual(0, it.next()); - assertTrue(it.hasNext()); - assertEqual(2, it.next()); - assertTrue(it.hasNext()); - assertEqual(4, it.next()); - assertTrue(it.hasNext()); - assertEqual(6, it.next()); - assertFalse(it.hasNext()); - } -} registerIteratorTest; + RegisterIterator it(regs); + assertTrue(it.hasNext()); + assertEqual(0, it.next()); + assertTrue(it.hasNext()); + assertEqual(2, it.next()); + assertTrue(it.hasNext()); + assertEqual(4, it.next()); + assertTrue(it.hasNext()); + assertEqual(6, it.next()); + assertFalse(it.hasNext()); +} diff --git a/unittest/test-harness.h b/unittest/test-harness.h index 29f86c236d..be50ff4233 100644 --- a/unittest/test-harness.h +++ b/unittest/test-harness.h @@ -15,38 +15,41 @@ #include class Test { -private: + private: Test* next; static Test* first; static Test** last; friend int main(int argc, char** argv); - - void print(uint64_t value) { + void print(uint64_t value) + { fprintf(stderr, "%p", reinterpret_cast(value)); } - void print(uint32_t value) { + void print(uint32_t value) + { fprintf(stderr, "%p", reinterpret_cast(value)); } - - void print(uint8_t value) { + void print(uint8_t value) + { print(static_cast(value)); } - void print(bool value) { + void print(bool value) + { fprintf(stderr, "%s", value ? "true" : "false"); } int failures; int runs; -protected: - template - void assertEqual(T expected, T actual) { - if(expected != actual) { + protected: + template + void assertEqual(T expected, T actual) + { + if (expected != actual) { fprintf(stderr, "assertion failure, expected: "); print(expected); fprintf(stderr, ", actual: "); @@ -57,17 +60,23 @@ protected: runs++; } - void assertEqual(const char* expected, const char* actual) { - if((expected == 0 && actual != 0) || (expected != 0 && actual == 0) || strcmp(expected, actual) != 0) { - fprintf(stderr, "assertion failure, expected: \"%s\", actual: \"%s\"\n", expected, actual); + void assertEqual(const char* expected, const char* actual) + { + if ((expected == 0 && actual != 0) || (expected != 0 && actual == 0) + || strcmp(expected, actual) != 0) { + fprintf(stderr, + "assertion failure, expected: \"%s\", actual: \"%s\"\n", + expected, + actual); failures++; } runs++; } - - template - void assertNotEqual(T expected, T actual) { - if(expected == actual) { + + template + void assertNotEqual(T expected, T actual) + { + if (expected == actual) { fprintf(stderr, "assertion failure, expected: not "); print(expected); fprintf(stderr, ", actual: "); @@ -78,15 +87,17 @@ protected: runs++; } - void assertTrue(bool value) { + void assertTrue(bool value) + { assertEqual(true, value); } - void assertFalse(bool value) { + void assertFalse(bool value) + { assertEqual(false, value); } -public: + public: const char* const name; Test(const char* name); @@ -95,4 +106,14 @@ public: static bool runAll(); }; -#endif // TEST_HARNESS_H +#define TEST(name) \ + class name##TestClass : public Test { \ + public: \ + name##TestClass() : Test(#name) \ + { \ + } \ + virtual void run(); \ + } name##TestInstance; \ + void name##TestClass::run() + +#endif // TEST_HARNESS_H diff --git a/unittest/util/arg-parser-test.cpp b/unittest/util/arg-parser-test.cpp index 631d481b2f..d5b195a989 100644 --- a/unittest/util/arg-parser-test.cpp +++ b/unittest/util/arg-parser-test.cpp @@ -19,51 +19,44 @@ using namespace avian::util; -class ArgParserTest : public Test { -public: - ArgParserTest(): - Test("ArgParser") - {} - - virtual void run() { - { - ArgParser parser; - Arg arg1(parser, false, "arg1", ""); - Arg required2(parser, true, "required2", ""); - const char* args[] = { - "myExecutable", - "-arg1", "myValue1", - "-required2", "myRequired2", - 0 - }; - assertTrue(parser.parse(sizeof(args) / sizeof(char*) - 1, args)); - assertEqual("myValue1", arg1.value); - assertEqual("myRequired2", required2.value); - } - - { - ArgParser parser; - Arg arg1(parser, false, "arg1", ""); - Arg required2(parser, true, "required2", ""); - const char* args[] = { - "myExecutable", - "-arg1", "myValue1", - "-required2", - 0 - }; - assertFalse(parser.parse(sizeof(args) / sizeof(char*) - 1, args)); - } - - { - ArgParser parser; - Arg arg1(parser, false, "arg1", ""); - Arg required2(parser, true, "required2", ""); - const char* args[] = { - "myExecutable", - "-arg1", "myValue1", - 0 - }; - assertFalse(parser.parse(sizeof(args) / sizeof(char*) - 1, args)); - } +TEST(ArgParser) { + { + ArgParser parser; + Arg arg1(parser, false, "arg1", ""); + Arg required2(parser, true, "required2", ""); + const char* args[] = { + "myExecutable", + "-arg1", "myValue1", + "-required2", "myRequired2", + 0 + }; + assertTrue(parser.parse(sizeof(args) / sizeof(char*) - 1, args)); + assertEqual("myValue1", arg1.value); + assertEqual("myRequired2", required2.value); } -} argParserTest; \ No newline at end of file + + { + ArgParser parser; + Arg arg1(parser, false, "arg1", ""); + Arg required2(parser, true, "required2", ""); + const char* args[] = { + "myExecutable", + "-arg1", "myValue1", + "-required2", + 0 + }; + assertFalse(parser.parse(sizeof(args) / sizeof(char*) - 1, args)); + } + + { + ArgParser parser; + Arg arg1(parser, false, "arg1", ""); + Arg required2(parser, true, "required2", ""); + const char* args[] = { + "myExecutable", + "-arg1", "myValue1", + 0 + }; + assertFalse(parser.parse(sizeof(args) / sizeof(char*) - 1, args)); + } +} From 1735a7976aa87bab6a0a0ea5a18e5bfb049f50f1 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 9 Feb 2014 14:58:47 -0700 Subject: [PATCH 3/4] do not omit calls to empty methods which may trigger class initialization There's a small optimization in compileDirectInvoke which tries to avoid generating calls to empty methods. However, this causes problems for code which uses such a call to ensure a class is initialized -- if we omit that call, the class may not be initialized and any side effects of that initialization may not happen when the program expects them to. This commit ensures that the compiler only omits empty method calls when the target class does not need initialization. It also removes commented-out code in classpath-openjdk.cpp which was responsible for loading libmawt proactively; that was a hack to get JogAmp to work before we understood what the real problem was. --- src/classpath-openjdk.cpp | 9 --------- src/compile.cpp | 6 +++++- test/Misc.java | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index f802abd347..4478159ef3 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -698,15 +698,6 @@ class MyClasspath : public Classpath { #else // not AVIAN_OPENJDK_SRC expect(t, loadLibrary(t, libraryPath, "verify", true, true)); expect(t, loadLibrary(t, libraryPath, "java", true, true)); -# ifndef PLATFORM_WINDOWS - // at one point, loading libmawt ahead of time was necessary to - // make AWT work, but recent versions of OpenJDK seem to take care - // of this from Java code, in which case loading it ahead of time - // actually causes trouble, so we comment it out for now until we - // know exactly when it's needed: - - //loadLibrary(t, libraryPath, "mawt", true, true, false); -# endif #endif // not AVIAN_OPENJDK_SRC { object assertionLock = resolveField diff --git a/src/compile.cpp b/src/compile.cpp index 7a968e176b..2d1703b7f4 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -3234,7 +3234,11 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall) Compiler::Operand* result = 0; - if (emptyMethod(t, target)) { + // don't bother calling an empty method unless calling it might + // cause the class to be initialized, which may have side effects + if (emptyMethod(t, target) + and (not classNeedsInit(t, methodClass(t, target)))) + { tailCall = false; } else { BootContext* bc = frame->context->bootContext; diff --git a/test/Misc.java b/test/Misc.java index 276fb56c21..22f7806b9e 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -23,6 +23,16 @@ public class Misc { } } + private static class Static { + static { + staticRan = true; + } + + public static void run() { } + } + + private static boolean staticRan; + private static int alpha; private static int beta; private static byte byte1, byte2, byte3; @@ -299,6 +309,10 @@ public class Misc { } catch (java.net.UnknownHostException e) { // cool } + + expect(! staticRan); + Static.run(); + expect(staticRan); } protected class Protected { } From d9ce351a246b28b2ca14d9265bf91a31976cc677 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Tue, 11 Feb 2014 14:54:43 -0700 Subject: [PATCH 4/4] Change ConcurrentLinkedQueue.poll(boolean remove) to private. Since it's not available in the Oracle classpath. Closes #169. --- classpath/java/util/concurrent/ConcurrentLinkedQueue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classpath/java/util/concurrent/ConcurrentLinkedQueue.java b/classpath/java/util/concurrent/ConcurrentLinkedQueue.java index 251adadbcc..ab6c0b344c 100644 --- a/classpath/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/classpath/java/util/concurrent/ConcurrentLinkedQueue.java @@ -56,7 +56,7 @@ public class ConcurrentLinkedQueue { return poll(true); } - public T poll(boolean remove) { + private T poll(boolean remove) { while (true) { Node h = head; Node t = tail;