< prev index next >

test/hotspot/gtest/classfile/test_symbolTable.cpp

Print this page

        

@@ -22,10 +22,11 @@
  */
 
 #include "precompiled.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "classfile/symbolTable.hpp"
+#include "threadHelper.inline.hpp"
 #include "unittest.hpp"
 
 TEST_VM(SymbolTable, temp_new_symbol) {
   // Assert messages assume these symbols are unique, and the refcounts start at
   // one, but code does not rely on this.

@@ -72,6 +73,78 @@
   { // inner scope
     TempNewSymbol s_inner = xyz;
   }
   ASSERT_EQ(xyz->refcount(), xyzcount - 1)
           << "Should have been decremented by dtor in inner scope";
+
+  // Test overflowing refcount making symbol permanent
+  Symbol* bigsym = SymbolTable::new_symbol("bigsym", CATCH);
+  for (int i = 0; i < PERM_REFCOUNT + 100; i++) {
+    bigsym->increment_refcount();
+  }
+  ASSERT_EQ(bigsym->refcount(), PERM_REFCOUNT) << "should not have overflowed";
+
+  // Test that PERM_REFCOUNT is sticky
+  for (int i = 0; i < PERM_REFCOUNT + 100; i++) {
+    bigsym->decrement_refcount();
+  }
+  ASSERT_EQ(bigsym->refcount(), PERM_REFCOUNT) << "should be sticky";
+}
+
+// TODO: Make two threads one decrementing the refcount and the other trying to increment.
+// try_increment_refcount should return false
+
+#define SYM_NAME_LENGTH 30
+static char symbol_name[SYM_NAME_LENGTH];
+
+class SymbolThread : public JavaTestThread {
+  public:
+  SymbolThread(Semaphore* post) : JavaTestThread(post) {}
+  virtual ~SymbolThread() {}
+  void main_run() {
+    Thread* THREAD = Thread::current();
+    for (int i = 0; i < 1000; i++) {
+      TempNewSymbol sym = SymbolTable::new_symbol(symbol_name, CATCH);
+      // Create and destroy new symbol
+      EXPECT_TRUE(sym->refcount() != 0) << "Symbol refcount unexpectedly zeroed";
+    }
+  }
+};
+
+#define SYM_TEST_THREAD_COUNT 5
+
+class DriverSymbolThread : public JavaTestThread {
+public:
+  Semaphore _done;
+  DriverSymbolThread(Semaphore* post) : JavaTestThread(post) { };
+  virtual ~DriverSymbolThread(){}
+
+  void main_run() {
+    Semaphore done(0);
+
+    Thread* THREAD = Thread::current();
+
+    // Find a symbol where there will probably be only one instance.
+    for (int i = 0; i < 100; i++) {
+       snprintf(symbol_name, SYM_NAME_LENGTH, "some_symbol%d", i);
+       TempNewSymbol ts = SymbolTable::new_symbol(symbol_name, CATCH);
+       if (ts->refcount() == 1) {
+         EXPECT_TRUE(ts->refcount() == 1) << "Symbol is just created";
+         break;  // found a unique symbol
+       }
+    }
+
+    SymbolThread* st[SYM_TEST_THREAD_COUNT];
+    for (int i = 0; i < SYM_TEST_THREAD_COUNT; i++) {
+      st[i] = new SymbolThread(&done);
+      st[i]->doit();
+    }
+
+    for (int i = 0; i < 4; i++) {
+      done.wait();
+    }
+  }
+};
+
+TEST_VM(SymbolTable, test_symbol_refcount_parallel) {
+  mt_test_doer<DriverSymbolThread>();
 }
< prev index next >