1 /*
 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.
 4  *
 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
 7  * published by the Free Software Foundation.
 8  *
 9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "code/dependencyContext.hpp"
27 #include "code/nmethod.hpp"
28 #include "unittest.hpp"
29 
30 class TestDependencyContext {
31  public:
32   char* _buffer[sizeof(nmethod) * 3];
33   nmethod* _nmethods[3];
34 
35   nmethodBucket* volatile _dependency_context;
36   volatile uint64_t _last_cleanup;
37 
38   DependencyContext dependencies() {
39     DependencyContext depContext(&_dependency_context, &_last_cleanup);
40     return depContext;
41   }
42 
43   TestDependencyContext()
44     : _dependency_context(NULL),
45       _last_cleanup(0) {
46     CodeCache_lock->lock_without_safepoint_check();
47 
48     memset(_buffer, 0, sizeof(nmethod) * 3);
49     _nmethods[0] = reinterpret_cast<nmethod*>(_buffer) + 0;
50     _nmethods[1] = reinterpret_cast<nmethod*>(_buffer) + 1;
51     _nmethods[2] = reinterpret_cast<nmethod*>(_buffer) + 2;
52 
53     _nmethods[0]->clear_unloading_state();
54     _nmethods[1]->clear_unloading_state();
55     _nmethods[2]->clear_unloading_state();
56 
57     dependencies().add_dependent_nmethod(_nmethods[2]);
58     dependencies().add_dependent_nmethod(_nmethods[1]);
59     dependencies().add_dependent_nmethod(_nmethods[0]);
60   }
61 
62   ~TestDependencyContext() {
63     wipe();
64     CodeCache_lock->unlock();
65   }
66 
67   void wipe() {
68     DependencyContext ctx(&_dependency_context, &_last_cleanup);
69     nmethodBucket* b = ctx.dependencies();
70     ctx.set_dependencies(NULL);
71     while (b != NULL) {
72       nmethodBucket* next = b->next();
73       delete b;
74       b = next;
75     }
76   }
77 };
78 
79 static void test_remove_dependent_nmethod(int id) {
80   TestDependencyContext c;
81   DependencyContext depContext = c.dependencies();
82 
83   nmethod* nm = c._nmethods[id];
84   depContext.remove_dependent_nmethod(nm);
85 
86   NOT_PRODUCT(ASSERT_FALSE(depContext.is_dependent_nmethod(nm)));
87 }
88 
89 TEST_VM(code, dependency_context) {
90   test_remove_dependent_nmethod(0);
91   test_remove_dependent_nmethod(1);
92   test_remove_dependent_nmethod(2);
93 }