/* * Copyright (c) 2015, 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. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #include "precompiled.hpp" #include "opto/compile.hpp" #include "opto/node.hpp" #include "opto/safepointTable.hpp" #include "runtime/sharedRuntime.hpp" Label &ThreadLocalSafepointTable::add_safepoint(InternalAddress safepoint_addr, bool is_return) { ThreadLocalSafepointEntry *entry = new (Compile::current()->comp_arena()) ThreadLocalSafepointEntry(safepoint_addr, is_return); int index = _safepoints.append(entry); return _safepoints.at(index)->_stub_label; } int ThreadLocalSafepointTable::stub_size() { return _safepoints.length() * 14 * 2; } #define __ _masm. void ThreadLocalSafepointTable::emit(CodeBuffer& cbuf, bool has_wide_vectors) { //cb->insts()->freeze(); MacroAssembler _masm(&cbuf); for (int i = _safepoints.length() - 1; i >= 0; i--) { ThreadLocalSafepointEntry &entry = *_safepoints.at(i); __ bind(entry._stub_label); __ push(rax); __ lea(rax, entry._safepoint_addr); __ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rax); __ pop(rax); address stub; if (entry._is_return) { assert(SharedRuntime::polling_page_return_handler_blob() != NULL, "polling page return stub not created yet"); stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); } else if (has_wide_vectors) { assert(SharedRuntime::polling_page_vectors_safepoint_handler_blob() != NULL, "polling page safepoint stub not created yet"); stub = SharedRuntime::polling_page_vectors_safepoint_handler_blob()->entry_point(); } else { assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL, "polling page safepoint stub not created yet"); stub = SharedRuntime::polling_page_safepoint_handler_blob()->entry_point(); } RuntimeAddress callback_addr(stub); __ jump(callback_addr); } } #undef __