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 } |