src/share/vm/prims/whitebox.cpp

Mon, 06 May 2013 17:19:42 +0200

author
tschatzl
date
Mon, 06 May 2013 17:19:42 +0200
changeset 5073
d17700c82d7d
parent 5040
9ce110b1d14a
child 5174
f54c85acc043
permissions
-rw-r--r--

8006088: Incompatible heap size flags accepted by VM
Summary: Make processing of minimum, initial and maximum heap size more intiutive by removing previous limitations on allowed values, and make error reporting consistent. Further, fix errors in ergonomic heap sizing.
Reviewed-by: johnc, jwilhelm, tamao

mgerdin@3619 1 /*
hseigel@4987 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
mgerdin@3619 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mgerdin@3619 4 *
mgerdin@3619 5 * This code is free software; you can redistribute it and/or modify it
mgerdin@3619 6 * under the terms of the GNU General Public License version 2 only, as
mgerdin@3619 7 * published by the Free Software Foundation.
mgerdin@3619 8 *
mgerdin@3619 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mgerdin@3619 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mgerdin@3619 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mgerdin@3619 12 * version 2 for more details (a copy is included in the LICENSE file that
mgerdin@3619 13 * accompanied this code).
mgerdin@3619 14 *
mgerdin@3619 15 * You should have received a copy of the GNU General Public License version
mgerdin@3619 16 * 2 along with this work; if not, write to the Free Software Foundation,
mgerdin@3619 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mgerdin@3619 18 *
mgerdin@3619 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mgerdin@3619 20 * or visit www.oracle.com if you need additional information or have any
mgerdin@3619 21 * questions.
mgerdin@3619 22 *
mgerdin@3619 23 */
mgerdin@3619 24
mgerdin@3619 25 #include "precompiled.hpp"
mgerdin@3619 26
mgerdin@3619 27 #include "memory/universe.hpp"
mgerdin@3619 28 #include "oops/oop.inline.hpp"
nloodin@3681 29
nloodin@3681 30 #include "classfile/symbolTable.hpp"
coleenp@4037 31 #include "classfile/classLoaderData.hpp"
nloodin@3681 32
mgerdin@3619 33 #include "prims/whitebox.hpp"
nloodin@3681 34 #include "prims/wbtestmethods/parserTests.hpp"
nloodin@3681 35
mgerdin@3619 36 #include "runtime/interfaceSupport.hpp"
mgerdin@3619 37 #include "runtime/os.hpp"
mgerdin@3619 38 #include "utilities/debug.hpp"
jprovino@4542 39 #include "utilities/macros.hpp"
mgerdin@3619 40
jprovino@4542 41 #if INCLUDE_ALL_GCS
mgerdin@3619 42 #include "gc_implementation/g1/concurrentMark.hpp"
mgerdin@3619 43 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
mgerdin@3619 44 #include "gc_implementation/g1/heapRegionRemSet.hpp"
jprovino@4542 45 #endif // INCLUDE_ALL_GCS
mgerdin@3619 46
ctornqvi@4512 47 #ifdef INCLUDE_NMT
ctornqvi@4512 48 #include "services/memTracker.hpp"
ctornqvi@4512 49 #endif // INCLUDE_NMT
ctornqvi@4512 50
iignatyev@4592 51 #include "compiler/compileBroker.hpp"
iignatyev@4908 52 #include "runtime/compilationPolicy.hpp"
iignatyev@4592 53
mgerdin@3619 54 bool WhiteBox::_used = false;
mgerdin@3619 55
mgerdin@3619 56 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
mgerdin@3619 57 return (jlong)(void*)JNIHandles::resolve(obj);
mgerdin@3619 58 WB_END
mgerdin@3619 59
mgerdin@3619 60 WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
mgerdin@3619 61 return heapOopSize;
mgerdin@3619 62 WB_END
mgerdin@3619 63
coleenp@4037 64
coleenp@4037 65 class WBIsKlassAliveClosure : public KlassClosure {
coleenp@4037 66 Symbol* _name;
coleenp@4037 67 bool _found;
coleenp@4037 68 public:
coleenp@4037 69 WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {}
coleenp@4037 70
coleenp@4037 71 void do_klass(Klass* k) {
coleenp@4037 72 if (_found) return;
coleenp@4037 73 Symbol* ksym = k->name();
coleenp@4037 74 if (ksym->fast_compare(_name) == 0) {
coleenp@4037 75 _found = true;
coleenp@4037 76 }
coleenp@4037 77 }
coleenp@4037 78
coleenp@4037 79 bool found() const {
coleenp@4037 80 return _found;
coleenp@4037 81 }
coleenp@4037 82 };
coleenp@4037 83
coleenp@4037 84 WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
coleenp@4037 85 Handle h_name = JNIHandles::resolve(name);
coleenp@4037 86 if (h_name.is_null()) return false;
coleenp@4037 87 Symbol* sym = java_lang_String::as_symbol(h_name, CHECK_false);
coleenp@4037 88 TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return
coleenp@4037 89
coleenp@4037 90 WBIsKlassAliveClosure closure(sym);
coleenp@4037 91 ClassLoaderDataGraph::classes_do(&closure);
coleenp@4037 92
coleenp@4037 93 return closure.found();
coleenp@4037 94 WB_END
coleenp@4037 95
tschatzl@5073 96 WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
tschatzl@5073 97 CollectorPolicy * p = Universe::heap()->collector_policy();
tschatzl@5073 98 gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
tschatzl@5073 99 SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Min alignment "SIZE_FORMAT" Max alignment "SIZE_FORMAT,
tschatzl@5073 100 p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
tschatzl@5073 101 p->min_alignment(), p->max_alignment());
tschatzl@5073 102 }
tschatzl@5073 103 WB_END
tschatzl@5073 104
jprovino@4542 105 #if INCLUDE_ALL_GCS
mgerdin@3619 106 WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
mgerdin@3619 107 G1CollectedHeap* g1 = G1CollectedHeap::heap();
mgerdin@3619 108 oop result = JNIHandles::resolve(obj);
mgerdin@3619 109 const HeapRegion* hr = g1->heap_region_containing(result);
mgerdin@3619 110 return hr->isHumongous();
mgerdin@3619 111 WB_END
mgerdin@3619 112
mgerdin@3619 113 WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
mgerdin@3619 114 G1CollectedHeap* g1 = G1CollectedHeap::heap();
mgerdin@3619 115 size_t nr = g1->free_regions();
mgerdin@3619 116 return (jlong)nr;
mgerdin@3619 117 WB_END
mgerdin@3619 118
mgerdin@3619 119 WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
mgerdin@3619 120 G1CollectedHeap* g1 = G1CollectedHeap::heap();
mgerdin@3619 121 ConcurrentMark* cm = g1->concurrent_mark();
mgerdin@3619 122 return cm->concurrent_marking_in_progress();
mgerdin@3619 123 WB_END
mgerdin@3619 124
mgerdin@3619 125 WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
mgerdin@3619 126 return (jint)HeapRegion::GrainBytes;
mgerdin@3619 127 WB_END
jprovino@4542 128 #endif // INCLUDE_ALL_GCS
mgerdin@3619 129
ctornqvi@4512 130 #ifdef INCLUDE_NMT
ctornqvi@4512 131 // Alloc memory using the test memory type so that we can use that to see if
ctornqvi@4512 132 // NMT picks it up correctly
ctornqvi@4885 133 WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
ctornqvi@4885 134 jlong addr = 0;
ctornqvi@4512 135
ctornqvi@4885 136 if (MemTracker::is_on() && !MemTracker::shutdown_in_progress()) {
ctornqvi@4885 137 addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
ctornqvi@4512 138 }
ctornqvi@4512 139
ctornqvi@4885 140 return addr;
ctornqvi@4512 141 WB_END
ctornqvi@4512 142
ctornqvi@4512 143 // Free the memory allocated by NMTAllocTest
ctornqvi@4885 144 WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem))
ctornqvi@4885 145 os::free((void*)(uintptr_t)mem, mtTest);
ctornqvi@4885 146 WB_END
ctornqvi@4512 147
ctornqvi@4885 148 WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
ctornqvi@4885 149 jlong addr = 0;
ctornqvi@4885 150
ctornqvi@4885 151 if (MemTracker::is_on() && !MemTracker::shutdown_in_progress()) {
ctornqvi@4885 152 addr = (jlong)(uintptr_t)os::reserve_memory(size);
ctornqvi@4885 153 MemTracker::record_virtual_memory_type((address)addr, mtTest);
ctornqvi@4512 154 }
ctornqvi@4512 155
ctornqvi@4885 156 return addr;
ctornqvi@4885 157 WB_END
ctornqvi@4512 158
ctornqvi@4885 159
ctornqvi@4885 160 WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
ctornqvi@4885 161 os::commit_memory((char *)(uintptr_t)addr, size);
ctornqvi@4885 162 MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
ctornqvi@4885 163 WB_END
ctornqvi@4885 164
ctornqvi@4885 165 WB_ENTRY(void, WB_NMTUncommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
ctornqvi@4885 166 os::uncommit_memory((char *)(uintptr_t)addr, size);
ctornqvi@4885 167 WB_END
ctornqvi@4885 168
ctornqvi@4885 169 WB_ENTRY(void, WB_NMTReleaseMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
ctornqvi@4885 170 os::release_memory((char *)(uintptr_t)addr, size);
ctornqvi@4512 171 WB_END
ctornqvi@4512 172
ctornqvi@4512 173 // Block until the current generation of NMT data to be merged, used to reliably test the NMT feature
ctornqvi@4512 174 WB_ENTRY(jboolean, WB_NMTWaitForDataMerge(JNIEnv* env))
ctornqvi@4512 175
ctornqvi@4512 176 if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
ctornqvi@4512 177 return false;
ctornqvi@4512 178 }
ctornqvi@4512 179
ctornqvi@4512 180 return MemTracker::wbtest_wait_for_data_merge();
ctornqvi@4512 181 WB_END
ctornqvi@4512 182
ctornqvi@4512 183 #endif // INCLUDE_NMT
ctornqvi@4512 184
iignatyev@4592 185 static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
iignatyev@4592 186 assert(method != NULL, "method should not be null");
iignatyev@4592 187 ThreadToNativeFromVM ttn(thread);
iignatyev@4592 188 return env->FromReflectedMethod(method);
iignatyev@4592 189 }
iignatyev@4592 190
iignatyev@4592 191 WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
iignatyev@4592 192 MutexLockerEx mu(Compile_lock);
iignatyev@4592 193 CodeCache::mark_all_nmethods_for_deoptimization();
iignatyev@4592 194 VM_Deoptimize op;
iignatyev@4592 195 VMThread::execute(&op);
iignatyev@4592 196 WB_END
iignatyev@4592 197
iignatyev@4592 198 WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method))
iignatyev@4592 199 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 200 MutexLockerEx mu(Compile_lock);
iignatyev@4592 201 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4592 202 int result = 0;
iignatyev@4592 203 nmethod* code = mh->code();
iignatyev@4592 204 if (code != NULL) {
iignatyev@4592 205 code->mark_for_deoptimization();
iignatyev@4592 206 ++result;
iignatyev@4592 207 }
iignatyev@4592 208 result += CodeCache::mark_for_deoptimization(mh());
iignatyev@4592 209 if (result > 0) {
iignatyev@4592 210 VM_Deoptimize op;
iignatyev@4592 211 VMThread::execute(&op);
iignatyev@4592 212 }
iignatyev@4592 213 return result;
iignatyev@4592 214 WB_END
iignatyev@4592 215
iignatyev@4592 216 WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method))
iignatyev@4592 217 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 218 MutexLockerEx mu(Compile_lock);
iignatyev@4592 219 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4592 220 nmethod* code = mh->code();
iignatyev@4592 221 if (code == NULL) {
iignatyev@4592 222 return JNI_FALSE;
iignatyev@4592 223 }
iignatyev@4592 224 return (code->is_alive() && !code->is_marked_for_deoptimization());
iignatyev@4592 225 WB_END
iignatyev@4592 226
iignatyev@4908 227 WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level))
iignatyev@4592 228 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 229 MutexLockerEx mu(Compile_lock);
iignatyev@4592 230 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4908 231 return CompilationPolicy::can_be_compiled(mh, comp_level);
iignatyev@4592 232 WB_END
iignatyev@4592 233
iignatyev@4592 234 WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
iignatyev@4592 235 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 236 MutexLockerEx mu(Compile_lock);
iignatyev@4592 237 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4592 238 return mh->queued_for_compilation();
iignatyev@4592 239 WB_END
iignatyev@4592 240
iignatyev@4592 241 WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method))
iignatyev@4592 242 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 243 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4592 244 nmethod* code = mh->code();
iignatyev@4592 245 return (code != NULL ? code->comp_level() : CompLevel_none);
iignatyev@4592 246 WB_END
iignatyev@4592 247
iignatyev@4592 248
iignatyev@4951 249 WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level))
iignatyev@4592 250 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 251 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4951 252 mh->set_not_compilable(comp_level, true /* report */, "WhiteBox");
iignatyev@4592 253 WB_END
iignatyev@4592 254
iignatyev@4908 255 WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
iignatyev@4592 256 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4592 257 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4592 258 bool result = mh->dont_inline();
iignatyev@4592 259 mh->set_dont_inline(value == JNI_TRUE);
iignatyev@4592 260 return result;
iignatyev@4592 261 WB_END
iignatyev@4592 262
iignatyev@4592 263 WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o))
iignatyev@4592 264 return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
iignatyev@4592 265 CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
iignatyev@4592 266 WB_END
iignatyev@4592 267
iignatyev@4908 268
iignatyev@4908 269 WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
iignatyev@4908 270 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4908 271 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4908 272 bool result = mh->force_inline();
iignatyev@4908 273 mh->set_force_inline(value == JNI_TRUE);
iignatyev@4908 274 return result;
iignatyev@4908 275 WB_END
iignatyev@4908 276
iignatyev@4908 277 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level))
iignatyev@4908 278 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4908 279 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4908 280 nmethod* nm = CompileBroker::compile_method(mh, InvocationEntryBci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
iignatyev@4908 281 MutexLockerEx mu(Compile_lock);
iignatyev@4908 282 return (mh->queued_for_compilation() || nm != NULL);
iignatyev@4908 283 WB_END
iignatyev@4908 284
iignatyev@4908 285 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
iignatyev@4908 286 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
iignatyev@4908 287 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
iignatyev@4908 288 MutexLockerEx mu(Compile_lock);
iignatyev@4908 289 MethodData* mdo = mh->method_data();
jiangli@4938 290 MethodCounters* mcs = mh->method_counters();
iignatyev@4908 291
iignatyev@4908 292 if (mdo != NULL) {
iignatyev@4908 293 mdo->init();
iignatyev@4908 294 ResourceMark rm;
iignatyev@4908 295 int arg_count = mdo->method()->size_of_parameters();
iignatyev@4908 296 for (int i = 0; i < arg_count; i++) {
iignatyev@4908 297 mdo->set_arg_modified(i, 0);
iignatyev@4908 298 }
iignatyev@4908 299 }
iignatyev@4908 300
iignatyev@4908 301 mh->clear_not_c1_compilable();
iignatyev@4908 302 mh->clear_not_c2_compilable();
iignatyev@4908 303 mh->clear_not_c2_osr_compilable();
iignatyev@4908 304 NOT_PRODUCT(mh->set_compiled_invocation_count(0));
jiangli@4938 305 if (mcs != NULL) {
jiangli@4938 306 mcs->backedge_counter()->init();
jiangli@4938 307 mcs->invocation_counter()->init();
jiangli@4938 308 mcs->set_interpreter_invocation_count(0);
jiangli@4938 309 mcs->set_interpreter_throwout_count(0);
iignatyev@4908 310
iignatyev@4908 311 #ifdef TIERED
jiangli@4938 312 mcs->set_rate(0.0F);
jiangli@4938 313 mh->set_prev_event_count(0, THREAD);
jiangli@4938 314 mh->set_prev_time(0, THREAD);
iignatyev@4908 315 #endif
jiangli@4938 316 }
iignatyev@4908 317 WB_END
iignatyev@4908 318
mgerdin@4850 319 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
mgerdin@4850 320 ResourceMark rm(THREAD);
mgerdin@4850 321 int len;
hseigel@4987 322 jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false);
hseigel@4987 323 return (StringTable::lookup(name, len) != NULL);
mgerdin@4850 324 WB_END
mgerdin@4850 325
mgerdin@4850 326
mgerdin@4850 327 WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
mgerdin@4850 328 Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
mgerdin@4850 329 Universe::heap()->collect(GCCause::_last_ditch_collection);
mgerdin@4850 330 WB_END
mgerdin@4850 331
mikael@4989 332
mikael@4989 333 WB_ENTRY(jlong, WB_ReserveMemory(JNIEnv* env, jobject o, jlong size))
mikael@4989 334 return (jlong)os::reserve_memory(size, NULL, 0);
mikael@4989 335 WB_END
mikael@4989 336
nloodin@3681 337 //Some convenience methods to deal with objects from java
nloodin@3681 338 int WhiteBox::offset_for_field(const char* field_name, oop object,
nloodin@3681 339 Symbol* signature_symbol) {
nloodin@3681 340 assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
nloodin@3681 341 Thread* THREAD = Thread::current();
nloodin@3681 342
nloodin@3681 343 //Get the class of our object
coleenp@4037 344 Klass* arg_klass = object->klass();
nloodin@3681 345 //Turn it into an instance-klass
coleenp@4037 346 InstanceKlass* ik = InstanceKlass::cast(arg_klass);
nloodin@3681 347
nloodin@3681 348 //Create symbols to look for in the class
nloodin@3681 349 TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name),
nloodin@3681 350 THREAD);
nloodin@3681 351
nloodin@3681 352 //To be filled in with an offset of the field we're looking for
nloodin@3681 353 fieldDescriptor fd;
nloodin@3681 354
coleenp@4037 355 Klass* res = ik->find_field(name_symbol, signature_symbol, &fd);
nloodin@3681 356 if (res == NULL) {
nloodin@3681 357 tty->print_cr("Invalid layout of %s at %s", ik->external_name(),
nloodin@3681 358 name_symbol->as_C_string());
nloodin@3681 359 fatal("Invalid layout of preloaded class");
nloodin@3681 360 }
nloodin@3681 361
nloodin@3681 362 //fetch the field at the offset we've found
nloodin@3681 363 int dest_offset = fd.offset();
nloodin@3681 364
nloodin@3681 365 return dest_offset;
nloodin@3681 366 }
nloodin@3681 367
nloodin@3681 368
nloodin@3681 369 const char* WhiteBox::lookup_jstring(const char* field_name, oop object) {
nloodin@3681 370 int offset = offset_for_field(field_name, object,
nloodin@3681 371 vmSymbols::string_signature());
nloodin@3681 372 oop string = object->obj_field(offset);
sla@3905 373 if (string == NULL) {
sla@3905 374 return NULL;
sla@3905 375 }
nloodin@3681 376 const char* ret = java_lang_String::as_utf8_string(string);
nloodin@3681 377 return ret;
nloodin@3681 378 }
nloodin@3681 379
nloodin@3681 380 bool WhiteBox::lookup_bool(const char* field_name, oop object) {
nloodin@3681 381 int offset =
nloodin@3681 382 offset_for_field(field_name, object, vmSymbols::bool_signature());
nloodin@3681 383 bool ret = (object->bool_field(offset) == JNI_TRUE);
nloodin@3681 384 return ret;
nloodin@3681 385 }
nloodin@3681 386
nloodin@3681 387
mgerdin@3619 388 #define CC (char*)
mgerdin@3619 389
mgerdin@3619 390 static JNINativeMethod methods[] = {
mgerdin@3619 391 {CC"getObjectAddress", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress },
mgerdin@3619 392 {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
iignatyev@4592 393 {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive },
iignatyev@4592 394 {CC"parseCommandLine",
iignatyev@4592 395 CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
nloodin@3681 396 (void*) &WB_ParseCommandLine
nloodin@3681 397 },
tschatzl@5073 398 {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes },
jprovino@4542 399 #if INCLUDE_ALL_GCS
mgerdin@3619 400 {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
mgerdin@3619 401 {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
mgerdin@3619 402 {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
mgerdin@3619 403 {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
jprovino@4542 404 #endif // INCLUDE_ALL_GCS
ctornqvi@4512 405 #ifdef INCLUDE_NMT
ctornqvi@4885 406 {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc },
ctornqvi@4885 407 {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree },
ctornqvi@4885 408 {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory },
ctornqvi@4885 409 {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
ctornqvi@4885 410 {CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
ctornqvi@4885 411 {CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
ctornqvi@4885 412 {CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge},
ctornqvi@4512 413 #endif // INCLUDE_NMT
iignatyev@4592 414 {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
iignatyev@4951 415 {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;)I",
iignatyev@4592 416 (void*)&WB_DeoptimizeMethod },
iignatyev@4951 417 {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;)Z",
iignatyev@4592 418 (void*)&WB_IsMethodCompiled },
iignatyev@4951 419 {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;I)Z",
iignatyev@4592 420 (void*)&WB_IsMethodCompilable},
iignatyev@4592 421 {CC"isMethodQueuedForCompilation",
iignatyev@4951 422 CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation},
iignatyev@4592 423 {CC"makeMethodNotCompilable",
iignatyev@4951 424 CC"(Ljava/lang/reflect/Executable;I)V", (void*)&WB_MakeMethodNotCompilable},
iignatyev@4908 425 {CC"testSetDontInlineMethod",
iignatyev@4951 426 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod},
iignatyev@4592 427 {CC"getMethodCompilationLevel",
iignatyev@4951 428 CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodCompilationLevel},
iignatyev@4592 429 {CC"getCompileQueuesSize",
iignatyev@4592 430 CC"()I", (void*)&WB_GetCompileQueuesSize},
iignatyev@4908 431 {CC"testSetForceInlineMethod",
iignatyev@4951 432 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod},
iignatyev@4908 433 {CC"enqueueMethodForCompilation",
iignatyev@4951 434 CC"(Ljava/lang/reflect/Executable;I)Z", (void*)&WB_EnqueueMethodForCompilation},
iignatyev@4908 435 {CC"clearMethodState",
iignatyev@4951 436 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
mgerdin@4850 437 {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
mgerdin@4850 438 {CC"fullGC", CC"()V", (void*)&WB_FullGC },
mikael@4989 439
mikael@4989 440 {CC"reserveMemory", CC"(J)J", (void*)&WB_ReserveMemory },
mgerdin@3619 441 };
mgerdin@3619 442
mgerdin@3619 443 #undef CC
mgerdin@3619 444
mgerdin@3619 445 JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
mgerdin@3619 446 {
mgerdin@3619 447 if (WhiteBoxAPI) {
mgerdin@3619 448 // Make sure that wbclass is loaded by the null classloader
mgerdin@3619 449 instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
mgerdin@3619 450 Handle loader(ikh->class_loader());
mgerdin@3619 451 if (loader.is_null()) {
iignatyev@5028 452 ResourceMark rm;
mgerdin@3619 453 ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
iignatyev@5028 454 bool result = true;
iignatyev@5028 455 // one by one registration natives for exception catching
iignatyev@5028 456 jclass exceptionKlass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string());
iignatyev@5028 457 for (int i = 0, n = sizeof(methods) / sizeof(methods[0]); i < n; ++i) {
iignatyev@5028 458 if (env->RegisterNatives(wbclass, methods + i, 1) != 0) {
iignatyev@5028 459 result = false;
iignatyev@5028 460 if (env->ExceptionCheck() && env->IsInstanceOf(env->ExceptionOccurred(), exceptionKlass)) {
iignatyev@5028 461 // j.l.NoSuchMethodError is thrown when a method can't be found or a method is not native
iignatyev@5028 462 // ignoring the exception
iignatyev@5028 463 tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", methods[i].name, methods[i].signature);
iignatyev@5028 464 env->ExceptionClear();
iignatyev@5028 465 } else {
iignatyev@5028 466 // register is failed w/o exception or w/ unexpected exception
iignatyev@5028 467 tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", methods[i].name, methods[i].signature);
iignatyev@5028 468 env->UnregisterNatives(wbclass);
iignatyev@5028 469 break;
iignatyev@5028 470 }
iignatyev@5028 471 }
iignatyev@5028 472 }
iignatyev@5028 473
iignatyev@5028 474 if (result) {
mgerdin@3619 475 WhiteBox::set_used();
mgerdin@3619 476 }
mgerdin@3619 477 }
mgerdin@3619 478 }
mgerdin@3619 479 }
mgerdin@3619 480 JVM_END

mercurial