src/hotspot/share/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Frames Patch New Old Previous File Next File open Cdiff src/hotspot/share/oops/methodData.cpp

src/hotspot/share/oops/methodData.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 844,853 **** --- 844,933 ---- return false; } return false; } + #if INCLUDE_JVMCI + + void* FailedSpeculation::operator new(size_t size, size_t fs_size) throw() { + return CHeapObj<mtCompiler>::operator new(fs_size, std::nothrow); + } + + FailedSpeculation::FailedSpeculation(address speculation, int speculation_len) : _data_len(speculation_len), _next(NULL) { + memcpy(data(), speculation, speculation_len); + } + + // A heuristic check to detect nmethods that outlive a failed speculations list. + static void guarantee_failed_speculations_alive(nmethod* nm, FailedSpeculation** failed_speculations_address) { + jlong head = (jlong)(address) *failed_speculations_address; + if ((head & 0x1) == 0x1) { + stringStream st; + if (nm != NULL) { + st.print("%d", nm->compile_id()); + Method* method = nm->method(); + st.print_raw("{"); + if (method != NULL) { + method->print_name(&st); + } else { + const char* jvmci_name = nm->jvmci_name(); + if (jvmci_name != NULL) { + st.print_raw(jvmci_name); + } + } + st.print_raw("}"); + } else { + st.print("<unknown>"); + } + fatal("Adding to failed speculations list that appears to have been freed. Source: %s", st.as_string()); + } + } + + bool FailedSpeculation::add_failed_speculation(nmethod* nm, FailedSpeculation** failed_speculations_address, address speculation, int speculation_len) { + assert(failed_speculations_address != NULL, "must be"); + size_t fs_size = sizeof(FailedSpeculation) + speculation_len; + FailedSpeculation* fs = new (fs_size) FailedSpeculation(speculation, speculation_len); + if (fs == NULL) { + // no memory -> ignore failed speculation + return false; + } + + guarantee(is_aligned(fs, sizeof(FailedSpeculation*)), "FailedSpeculation objects must be pointer aligned"); + guarantee_failed_speculations_alive(nm, failed_speculations_address); + + FailedSpeculation** cursor = failed_speculations_address; + do { + if (*cursor == NULL) { + FailedSpeculation* old_fs = Atomic::cmpxchg(fs, cursor, (FailedSpeculation*) NULL); + if (old_fs == NULL) { + // Successfully appended fs to end of the list + return true; + } + cursor = old_fs->next_adr(); + } else { + cursor = (*cursor)->next_adr(); + } + } while (true); + } + + void FailedSpeculation::free_failed_speculations(FailedSpeculation** failed_speculations_address) { + assert(failed_speculations_address != NULL, "must be"); + FailedSpeculation* fs = *failed_speculations_address; + while (fs != NULL) { + FailedSpeculation* next = fs->next(); + delete fs; + fs = next; + } + + // Write an unaligned value to failed_speculations_address to denote + // that it is no longer a valid pointer. This is allows for the check + // in add_failed_speculation against adding to a freed failed + // speculations list. + long* head = (long*) failed_speculations_address; + (*head) = (*head) | 0x1; + } + #endif // INCLUDE_JVMCI + int MethodData::compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps) { #if INCLUDE_JVMCI if (ProfileTraps) { // Assume that up to 30% of the possibly trapping BCIs with no MDP will need to allocate one. int extra_data_count = MIN2(empty_bc_count, MAX2(4, (empty_bc_count * 30) / 100));
*** 1225,1234 **** --- 1305,1315 ---- _num_blocks = 0; _would_profile = unknown; #if INCLUDE_JVMCI _jvmci_ir_size = 0; + _failed_speculations = NULL; #endif #if INCLUDE_RTM_OPT _rtm_state = NoRTM; // No RTM lock eliding by default if (UseRTMLocking &&
src/hotspot/share/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Frames Patch New Old Previous File Next File