test/hotspot/gtest/classfile/test_symbolTable.cpp
changeset 51179 516acf6956a2
parent 49449 ef5d5d343e2a
child 51262 d4b9a434af84
equal deleted inserted replaced
51178:416a76fe8067 51179:516acf6956a2
     1 /*
     1 /*
     2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    22  */
    22  */
    23 
    23 
    24 #include "precompiled.hpp"
    24 #include "precompiled.hpp"
    25 #include "runtime/interfaceSupport.inline.hpp"
    25 #include "runtime/interfaceSupport.inline.hpp"
    26 #include "classfile/symbolTable.hpp"
    26 #include "classfile/symbolTable.hpp"
       
    27 #include "threadHelper.inline.hpp"
    27 #include "unittest.hpp"
    28 #include "unittest.hpp"
    28 
    29 
    29 TEST_VM(SymbolTable, temp_new_symbol) {
    30 TEST_VM(SymbolTable, temp_new_symbol) {
    30   // Assert messages assume these symbols are unique, and the refcounts start at
    31   // Assert messages assume these symbols are unique, and the refcounts start at
    31   // one, but code does not rely on this.
    32   // one, but code does not rely on this.
    72   { // inner scope
    73   { // inner scope
    73     TempNewSymbol s_inner = xyz;
    74     TempNewSymbol s_inner = xyz;
    74   }
    75   }
    75   ASSERT_EQ(xyz->refcount(), xyzcount - 1)
    76   ASSERT_EQ(xyz->refcount(), xyzcount - 1)
    76           << "Should have been decremented by dtor in inner scope";
    77           << "Should have been decremented by dtor in inner scope";
       
    78 
       
    79   // Test overflowing refcount making symbol permanent
       
    80   Symbol* bigsym = SymbolTable::new_symbol("bigsym", CATCH);
       
    81   for (int i = 0; i < PERM_REFCOUNT + 100; i++) {
       
    82     bigsym->increment_refcount();
       
    83   }
       
    84   ASSERT_EQ(bigsym->refcount(), PERM_REFCOUNT) << "should not have overflowed";
       
    85 
       
    86   // Test that PERM_REFCOUNT is sticky
       
    87   for (int i = 0; i < 10; i++) {
       
    88     bigsym->decrement_refcount();
       
    89   }
       
    90   ASSERT_EQ(bigsym->refcount(), PERM_REFCOUNT) << "should be sticky";
    77 }
    91 }
       
    92 
       
    93 // TODO: Make two threads one decrementing the refcount and the other trying to increment.
       
    94 // try_increment_refcount should return false
       
    95 
       
    96 #define SYM_NAME_LENGTH 30
       
    97 static char symbol_name[SYM_NAME_LENGTH];
       
    98 
       
    99 class SymbolThread : public JavaTestThread {
       
   100   public:
       
   101   SymbolThread(Semaphore* post) : JavaTestThread(post) {}
       
   102   virtual ~SymbolThread() {}
       
   103   void main_run() {
       
   104     Thread* THREAD = Thread::current();
       
   105     for (int i = 0; i < 1000; i++) {
       
   106       TempNewSymbol sym = SymbolTable::new_symbol(symbol_name, CATCH);
       
   107       // Create and destroy new symbol
       
   108       EXPECT_TRUE(sym->refcount() != 0) << "Symbol refcount unexpectedly zeroed";
       
   109     }
       
   110   }
       
   111 };
       
   112 
       
   113 #define SYM_TEST_THREAD_COUNT 5
       
   114 
       
   115 class DriverSymbolThread : public JavaTestThread {
       
   116 public:
       
   117   Semaphore _done;
       
   118   DriverSymbolThread(Semaphore* post) : JavaTestThread(post) { };
       
   119   virtual ~DriverSymbolThread(){}
       
   120 
       
   121   void main_run() {
       
   122     Semaphore done(0);
       
   123 
       
   124     Thread* THREAD = Thread::current();
       
   125 
       
   126     // Find a symbol where there will probably be only one instance.
       
   127     for (int i = 0; i < 100; i++) {
       
   128        snprintf(symbol_name, SYM_NAME_LENGTH, "some_symbol%d", i);
       
   129        TempNewSymbol ts = SymbolTable::new_symbol(symbol_name, CATCH);
       
   130        if (ts->refcount() == 1) {
       
   131          EXPECT_TRUE(ts->refcount() == 1) << "Symbol is just created";
       
   132          break;  // found a unique symbol
       
   133        }
       
   134     }
       
   135 
       
   136     SymbolThread* st[SYM_TEST_THREAD_COUNT];
       
   137     for (int i = 0; i < SYM_TEST_THREAD_COUNT; i++) {
       
   138       st[i] = new SymbolThread(&done);
       
   139       st[i]->doit();
       
   140     }
       
   141 
       
   142     for (int i = 0; i < 4; i++) {
       
   143       done.wait();
       
   144     }
       
   145   }
       
   146 };
       
   147 
       
   148 TEST_VM(SymbolTable, test_symbol_refcount_parallel) {
       
   149   mt_test_doer<DriverSymbolThread>();
       
   150 }