1 /*
2 * Copyright (c) 1997, 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 *
2546
2547 private:
2548
2549 #ifndef PRODUCT
2550 static int _lookups; // number of calls to lookup
2551 static int _buckets; // number of buckets checked
2552 static int _equals; // number of buckets checked with matching hash
2553 static int _hits; // number of successful lookups
2554 static int _compact; // number of equals calls with compact signature
2555 #endif
2556
2557 AdapterHandlerEntry* bucket(int i) {
2558 return (AdapterHandlerEntry*)BasicHashtable<mtCode>::bucket(i);
2559 }
2560
2561 public:
2562 AdapterHandlerTable()
2563 : BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
2564
2565 // Create a new entry suitable for insertion in the table
2566 AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_value_entry, address c2i_value_ro_entry, address c2i_unverified_entry) {
2567 AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
2568 entry->init(fingerprint, i2c_entry, c2i_entry, c2i_value_entry, c2i_value_ro_entry, c2i_unverified_entry);
2569 if (DumpSharedSpaces) {
2570 ((CDSAdapterHandlerEntry*)entry)->init();
2571 }
2572 return entry;
2573 }
2574
2575 // Insert an entry into the table
2576 void add(AdapterHandlerEntry* entry) {
2577 int index = hash_to_index(entry->hash());
2578 add_entry(index, entry);
2579 }
2580
2581 void free_entry(AdapterHandlerEntry* entry) {
2582 entry->deallocate();
2583 BasicHashtable<mtCode>::free_entry(entry);
2584 }
2585
2586 // Find a entry with the same fingerprint if it exists
2587 AdapterHandlerEntry* lookup(const GrowableArray<SigEntry>* sig, bool has_ro_adapter = false) {
2588 NOT_PRODUCT(_lookups++);
2691 _buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size);
2692 return _buffer;
2693 }
2694
2695 extern "C" void unexpected_adapter_call() {
2696 ShouldNotCallThis();
2697 }
2698
2699 void AdapterHandlerLibrary::initialize() {
2700 if (_adapters != NULL) return;
2701 _adapters = new AdapterHandlerTable();
2702
2703 // Create a special handler for abstract methods. Abstract methods
2704 // are never compiled so an i2c entry is somewhat meaningless, but
2705 // throw AbstractMethodError just in case.
2706 // Pass wrong_method_abstract for the c2i transitions to return
2707 // AbstractMethodError for invalid invocations.
2708 address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
2709 _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(NULL),
2710 StubRoutines::throw_AbstractMethodError_entry(),
2711 wrong_method_abstract, wrong_method_abstract, wrong_method_abstract, wrong_method_abstract);
2712 }
2713
2714 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
2715 address i2c_entry,
2716 address c2i_entry,
2717 address c2i_value_entry,
2718 address c2i_value_ro_entry,
2719 address c2i_unverified_entry) {
2720 return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_value_entry, c2i_value_ro_entry, c2i_unverified_entry);
2721 }
2722
2723 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
2724 AdapterHandlerEntry* entry = get_adapter0(method);
2725 if (method->is_shared()) {
2726 // See comments around Method::link_method()
2727 MutexLocker mu(AdapterHandlerLibrary_lock);
2728 if (method->adapter() == NULL) {
2729 method->update_adapter_trampoline(entry);
2730 }
2731 address trampoline = method->from_compiled_entry();
2732 if (*(int*)trampoline == 0) {
2733 CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
2734 MacroAssembler _masm(&buffer);
2735 SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
2736 assert(*(int*)trampoline != 0, "Instruction(s) for trampoline must not be encoded as zeros.");
2737
2738 if (PrintInterpreter) {
2739 Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
2740 }
2924 GrowableArray<SigEntry>& sig_cc_ro = ces.sig_cc_ro();
2925 VMRegPair* regs = ces.regs();
2926 VMRegPair* regs_cc = ces.regs_cc();
2927 VMRegPair* regs_cc_ro = ces.regs_cc_ro();
2928 int args_on_stack = ces.args_on_stack();
2929 int args_on_stack_cc = ces.args_on_stack_cc();
2930 int args_on_stack_cc_ro = ces.args_on_stack_cc_ro();
2931
2932 if (ces.has_scalarized_args()) {
2933 method->set_has_scalarized_args(true);
2934 method->set_c1_needs_stack_repair(ces.c1_needs_stack_repair());
2935 method->set_c2_needs_stack_repair(ces.c2_needs_stack_repair());
2936 }
2937
2938 if (method->is_abstract()) {
2939 // Save a C heap allocated version of the signature for abstract methods with scalarized value type arguments
2940 assert(ValueTypePassFieldsAsArgs && has_value_arg, "must have scalarized value type args");
2941 address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
2942 entry = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(NULL),
2943 StubRoutines::throw_AbstractMethodError_entry(),
2944 wrong_method_abstract, wrong_method_abstract, wrong_method_abstract, wrong_method_abstract);
2945 GrowableArray<SigEntry>* heap_sig = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<SigEntry>(sig_cc_ro.length(), true);
2946 heap_sig->appendAll(&sig_cc_ro);
2947 entry->set_sig_cc(heap_sig);
2948 return entry;
2949 }
2950
2951 // Lookup method signature's fingerprint
2952 entry = _adapters->lookup(&sig_cc, regs_cc != regs_cc_ro);
2953
2954 #ifdef ASSERT
2955 AdapterHandlerEntry* shared_entry = NULL;
2956 // Start adapter sharing verification only after the VM is booted.
2957 if (VerifyAdapterSharing && (entry != NULL)) {
2958 shared_entry = entry;
2959 entry = NULL;
2960 }
2961 #endif
2962
2963 if (entry != NULL) {
2964 return entry;
3057 "%s(%s)@" PTR_FORMAT,
3058 new_adapter->name(),
3059 fingerprint->as_string(),
3060 new_adapter->content_begin());
3061 Forte::register_stub(blob_id, new_adapter->content_begin(), new_adapter->content_end());
3062
3063 if (JvmtiExport::should_post_dynamic_code_generated()) {
3064 JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end());
3065 }
3066 }
3067 return entry;
3068 }
3069
3070 address AdapterHandlerEntry::base_address() {
3071 address base = _i2c_entry;
3072 if (base == NULL) base = _c2i_entry;
3073 assert(base <= _c2i_entry || _c2i_entry == NULL, "");
3074 assert(base <= _c2i_value_entry || _c2i_value_entry == NULL, "");
3075 assert(base <= _c2i_value_ro_entry || _c2i_value_ro_entry == NULL, "");
3076 assert(base <= _c2i_unverified_entry || _c2i_unverified_entry == NULL, "");
3077 return base;
3078 }
3079
3080 void AdapterHandlerEntry::relocate(address new_base) {
3081 address old_base = base_address();
3082 assert(old_base != NULL, "");
3083 ptrdiff_t delta = new_base - old_base;
3084 if (_i2c_entry != NULL)
3085 _i2c_entry += delta;
3086 if (_c2i_entry != NULL)
3087 _c2i_entry += delta;
3088 if (_c2i_value_entry != NULL)
3089 _c2i_value_entry += delta;
3090 if (_c2i_value_ro_entry != NULL)
3091 _c2i_value_ro_entry += delta;
3092 if (_c2i_unverified_entry != NULL)
3093 _c2i_unverified_entry += delta;
3094 assert(base_address() == new_base, "");
3095 }
3096
3097
3098 void AdapterHandlerEntry::deallocate() {
3099 delete _fingerprint;
3100 if (_sig_cc != NULL) {
3101 delete _sig_cc;
3102 }
3103 #ifdef ASSERT
3104 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code);
3105 #endif
3106 }
3107
3108
3109 #ifdef ASSERT
3110 // Capture the code before relocation so that it can be compared
3111 // against other versions. If the code is captured after relocation
3112 // then relative instructions won't be equivalent.
3113 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) {
3420 AdapterHandlerEntry* a = iter.next();
3421 if (b == CodeCache::find_blob(a->get_i2c_entry())) return true;
3422 }
3423 return false;
3424 }
3425
3426 void AdapterHandlerLibrary::print_handler_on(outputStream* st, const CodeBlob* b) {
3427 AdapterHandlerTableIterator iter(_adapters);
3428 while (iter.has_next()) {
3429 AdapterHandlerEntry* a = iter.next();
3430 if (b == CodeCache::find_blob(a->get_i2c_entry())) {
3431 st->print("Adapter for signature: ");
3432 a->print_adapter_on(tty);
3433 return;
3434 }
3435 }
3436 assert(false, "Should have found handler");
3437 }
3438
3439 void AdapterHandlerEntry::print_adapter_on(outputStream* st) const {
3440 st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iVE: " INTPTR_FORMAT " c2iVROE: " INTPTR_FORMAT " c2iUE: " INTPTR_FORMAT,
3441 p2i(this), fingerprint()->as_string(),
3442 p2i(get_i2c_entry()), p2i(get_c2i_entry()), p2i(get_c2i_value_entry()), p2i(get_c2i_value_ro_entry()), p2i(get_c2i_unverified_entry()));
3443
3444 }
3445
3446 #if INCLUDE_CDS
3447
3448 void CDSAdapterHandlerEntry::init() {
3449 assert(DumpSharedSpaces, "used during dump time only");
3450 _c2i_entry_trampoline = (address)MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size());
3451 _adapter_trampoline = (AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*));
3452 };
3453
3454 #endif // INCLUDE_CDS
3455
3456
3457 #ifndef PRODUCT
3458
3459 void AdapterHandlerLibrary::print_statistics() {
3460 _adapters->print_statistics();
3461 }
3462
|
1 /*
2 * Copyright (c) 1997, 2019, 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 *
2546
2547 private:
2548
2549 #ifndef PRODUCT
2550 static int _lookups; // number of calls to lookup
2551 static int _buckets; // number of buckets checked
2552 static int _equals; // number of buckets checked with matching hash
2553 static int _hits; // number of successful lookups
2554 static int _compact; // number of equals calls with compact signature
2555 #endif
2556
2557 AdapterHandlerEntry* bucket(int i) {
2558 return (AdapterHandlerEntry*)BasicHashtable<mtCode>::bucket(i);
2559 }
2560
2561 public:
2562 AdapterHandlerTable()
2563 : BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
2564
2565 // Create a new entry suitable for insertion in the table
2566 AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry,
2567 address c2i_value_entry, address c2i_value_ro_entry,
2568 address c2i_unverified_entry, address c2i_unverified_value_entry) {
2569 AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
2570 entry->init(fingerprint, i2c_entry, c2i_entry, c2i_value_entry, c2i_value_ro_entry,
2571 c2i_unverified_entry, c2i_unverified_value_entry);
2572 if (DumpSharedSpaces) {
2573 ((CDSAdapterHandlerEntry*)entry)->init();
2574 }
2575 return entry;
2576 }
2577
2578 // Insert an entry into the table
2579 void add(AdapterHandlerEntry* entry) {
2580 int index = hash_to_index(entry->hash());
2581 add_entry(index, entry);
2582 }
2583
2584 void free_entry(AdapterHandlerEntry* entry) {
2585 entry->deallocate();
2586 BasicHashtable<mtCode>::free_entry(entry);
2587 }
2588
2589 // Find a entry with the same fingerprint if it exists
2590 AdapterHandlerEntry* lookup(const GrowableArray<SigEntry>* sig, bool has_ro_adapter = false) {
2591 NOT_PRODUCT(_lookups++);
2694 _buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size);
2695 return _buffer;
2696 }
2697
2698 extern "C" void unexpected_adapter_call() {
2699 ShouldNotCallThis();
2700 }
2701
2702 void AdapterHandlerLibrary::initialize() {
2703 if (_adapters != NULL) return;
2704 _adapters = new AdapterHandlerTable();
2705
2706 // Create a special handler for abstract methods. Abstract methods
2707 // are never compiled so an i2c entry is somewhat meaningless, but
2708 // throw AbstractMethodError just in case.
2709 // Pass wrong_method_abstract for the c2i transitions to return
2710 // AbstractMethodError for invalid invocations.
2711 address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
2712 _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(NULL),
2713 StubRoutines::throw_AbstractMethodError_entry(),
2714 wrong_method_abstract, wrong_method_abstract, wrong_method_abstract,
2715 wrong_method_abstract, wrong_method_abstract);
2716 }
2717
2718 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
2719 address i2c_entry,
2720 address c2i_entry,
2721 address c2i_value_entry,
2722 address c2i_value_ro_entry,
2723 address c2i_unverified_entry,
2724 address c2i_unverified_value_entry) {
2725 return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_value_entry, c2i_value_ro_entry, c2i_unverified_entry,
2726 c2i_unverified_value_entry);
2727 }
2728
2729 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
2730 AdapterHandlerEntry* entry = get_adapter0(method);
2731 if (method->is_shared()) {
2732 // See comments around Method::link_method()
2733 MutexLocker mu(AdapterHandlerLibrary_lock);
2734 if (method->adapter() == NULL) {
2735 method->update_adapter_trampoline(entry);
2736 }
2737 address trampoline = method->from_compiled_entry();
2738 if (*(int*)trampoline == 0) {
2739 CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
2740 MacroAssembler _masm(&buffer);
2741 SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
2742 assert(*(int*)trampoline != 0, "Instruction(s) for trampoline must not be encoded as zeros.");
2743
2744 if (PrintInterpreter) {
2745 Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
2746 }
2930 GrowableArray<SigEntry>& sig_cc_ro = ces.sig_cc_ro();
2931 VMRegPair* regs = ces.regs();
2932 VMRegPair* regs_cc = ces.regs_cc();
2933 VMRegPair* regs_cc_ro = ces.regs_cc_ro();
2934 int args_on_stack = ces.args_on_stack();
2935 int args_on_stack_cc = ces.args_on_stack_cc();
2936 int args_on_stack_cc_ro = ces.args_on_stack_cc_ro();
2937
2938 if (ces.has_scalarized_args()) {
2939 method->set_has_scalarized_args(true);
2940 method->set_c1_needs_stack_repair(ces.c1_needs_stack_repair());
2941 method->set_c2_needs_stack_repair(ces.c2_needs_stack_repair());
2942 }
2943
2944 if (method->is_abstract()) {
2945 // Save a C heap allocated version of the signature for abstract methods with scalarized value type arguments
2946 assert(ValueTypePassFieldsAsArgs && has_value_arg, "must have scalarized value type args");
2947 address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
2948 entry = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(NULL),
2949 StubRoutines::throw_AbstractMethodError_entry(),
2950 wrong_method_abstract, wrong_method_abstract, wrong_method_abstract,
2951 wrong_method_abstract, wrong_method_abstract);
2952 GrowableArray<SigEntry>* heap_sig = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<SigEntry>(sig_cc_ro.length(), true);
2953 heap_sig->appendAll(&sig_cc_ro);
2954 entry->set_sig_cc(heap_sig);
2955 return entry;
2956 }
2957
2958 // Lookup method signature's fingerprint
2959 entry = _adapters->lookup(&sig_cc, regs_cc != regs_cc_ro);
2960
2961 #ifdef ASSERT
2962 AdapterHandlerEntry* shared_entry = NULL;
2963 // Start adapter sharing verification only after the VM is booted.
2964 if (VerifyAdapterSharing && (entry != NULL)) {
2965 shared_entry = entry;
2966 entry = NULL;
2967 }
2968 #endif
2969
2970 if (entry != NULL) {
2971 return entry;
3064 "%s(%s)@" PTR_FORMAT,
3065 new_adapter->name(),
3066 fingerprint->as_string(),
3067 new_adapter->content_begin());
3068 Forte::register_stub(blob_id, new_adapter->content_begin(), new_adapter->content_end());
3069
3070 if (JvmtiExport::should_post_dynamic_code_generated()) {
3071 JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end());
3072 }
3073 }
3074 return entry;
3075 }
3076
3077 address AdapterHandlerEntry::base_address() {
3078 address base = _i2c_entry;
3079 if (base == NULL) base = _c2i_entry;
3080 assert(base <= _c2i_entry || _c2i_entry == NULL, "");
3081 assert(base <= _c2i_value_entry || _c2i_value_entry == NULL, "");
3082 assert(base <= _c2i_value_ro_entry || _c2i_value_ro_entry == NULL, "");
3083 assert(base <= _c2i_unverified_entry || _c2i_unverified_entry == NULL, "");
3084 assert(base <= _c2i_unverified_value_entry || _c2i_unverified_value_entry == NULL, "");
3085 return base;
3086 }
3087
3088 void AdapterHandlerEntry::relocate(address new_base) {
3089 address old_base = base_address();
3090 assert(old_base != NULL, "");
3091 ptrdiff_t delta = new_base - old_base;
3092 if (_i2c_entry != NULL)
3093 _i2c_entry += delta;
3094 if (_c2i_entry != NULL)
3095 _c2i_entry += delta;
3096 if (_c2i_value_entry != NULL)
3097 _c2i_value_entry += delta;
3098 if (_c2i_value_ro_entry != NULL)
3099 _c2i_value_ro_entry += delta;
3100 if (_c2i_unverified_entry != NULL)
3101 _c2i_unverified_entry += delta;
3102 if (_c2i_unverified_value_entry != NULL)
3103 _c2i_unverified_value_entry += delta;
3104 assert(base_address() == new_base, "");
3105 }
3106
3107
3108 void AdapterHandlerEntry::deallocate() {
3109 delete _fingerprint;
3110 if (_sig_cc != NULL) {
3111 delete _sig_cc;
3112 }
3113 #ifdef ASSERT
3114 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code);
3115 #endif
3116 }
3117
3118
3119 #ifdef ASSERT
3120 // Capture the code before relocation so that it can be compared
3121 // against other versions. If the code is captured after relocation
3122 // then relative instructions won't be equivalent.
3123 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) {
3430 AdapterHandlerEntry* a = iter.next();
3431 if (b == CodeCache::find_blob(a->get_i2c_entry())) return true;
3432 }
3433 return false;
3434 }
3435
3436 void AdapterHandlerLibrary::print_handler_on(outputStream* st, const CodeBlob* b) {
3437 AdapterHandlerTableIterator iter(_adapters);
3438 while (iter.has_next()) {
3439 AdapterHandlerEntry* a = iter.next();
3440 if (b == CodeCache::find_blob(a->get_i2c_entry())) {
3441 st->print("Adapter for signature: ");
3442 a->print_adapter_on(tty);
3443 return;
3444 }
3445 }
3446 assert(false, "Should have found handler");
3447 }
3448
3449 void AdapterHandlerEntry::print_adapter_on(outputStream* st) const {
3450 st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iVE: " INTPTR_FORMAT
3451 " c2iVROE: " INTPTR_FORMAT " c2iUE: " INTPTR_FORMAT " c2iUVE: " INTPTR_FORMAT,
3452 p2i(this), fingerprint()->as_string(),
3453 p2i(get_i2c_entry()), p2i(get_c2i_entry()), p2i(get_c2i_value_entry()),
3454 p2i(get_c2i_value_ro_entry()), p2i(get_c2i_unverified_entry()), p2i(get_c2i_unverified_value_entry()));
3455
3456 }
3457
3458 #if INCLUDE_CDS
3459
3460 void CDSAdapterHandlerEntry::init() {
3461 assert(DumpSharedSpaces, "used during dump time only");
3462 _c2i_entry_trampoline = (address)MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size());
3463 _adapter_trampoline = (AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*));
3464 };
3465
3466 #endif // INCLUDE_CDS
3467
3468
3469 #ifndef PRODUCT
3470
3471 void AdapterHandlerLibrary::print_statistics() {
3472 _adapters->print_statistics();
3473 }
3474
|