1 /*
  2  * Copyright (c) 1997, 2020, 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 "asm/macroAssembler.hpp"
 27 #include "asm/macroAssembler.inline.hpp"
 28 #include "compiler/disassembler.hpp"
 29 #include "interpreter/interpreter.hpp"
 30 #include "interpreter/interpreterRuntime.hpp"
 31 #include "interpreter/interp_masm.hpp"
 32 #include "interpreter/templateTable.hpp"
 33 #include "memory/allocation.inline.hpp"
 34 #include "memory/resourceArea.hpp"
 35 #include "oops/arrayOop.hpp"
 36 #include "oops/methodData.hpp"
 37 #include "oops/method.hpp"
 38 #include "oops/oop.inline.hpp"
 39 #include "prims/forte.hpp"
 40 #include "prims/jvmtiExport.hpp"
 41 #include "prims/methodHandles.hpp"
 42 #include "runtime/handles.inline.hpp"
 43 #include "runtime/sharedRuntime.hpp"
 44 #include "runtime/stubRoutines.hpp"
 45 #include "runtime/timer.hpp"
 46 
 47 # define __ _masm->
 48 
 49 
 50 //------------------------------------------------------------------------------
 51 // Implementation of InterpreterCodelet
 52 
 53 void InterpreterCodelet::initialize(const char* description, Bytecodes::Code bytecode) {
 54   _description = description;
 55   _bytecode    = bytecode;
 56 #ifndef PRODUCT
 57   AsmRemarks* arp = new(&_asm_remarks) AsmRemarks();
 58   DbgStrings* dsp = new(&_dbg_strings) DbgStrings();
 59   postcond(arp == &_asm_remarks);
 60   postcond(dsp == &_dbg_strings);
 61 #endif
 62 }
 63 
 64 void InterpreterCodelet::verify() {}
 65 
 66 void InterpreterCodelet::print_on(outputStream* st) const {
 67   ttyLocker ttyl;
 68 
 69   if (PrintInterpreter) {
 70     st->cr();
 71     st->print_cr("----------------------------------------------------------------------");
 72   }
 73 
 74   if (description() != NULL) st->print("%s  ", description());
 75   if (bytecode()    >= 0   ) st->print("%d %s  ", bytecode(), Bytecodes::name(bytecode()));
 76   st->print_cr("[" INTPTR_FORMAT ", " INTPTR_FORMAT "]  %d bytes",
 77                 p2i(code_begin()), p2i(code_end()), code_size());
 78 
 79   if (PrintInterpreter) {
 80     st->cr();
 81     Disassembler::decode(code_begin(), code_end(), st NOT_PRODUCT(COMMA &_asm_remarks));
 82   }
 83 }
 84 
 85 void InterpreterCodelet::print() const { print_on(tty); }
 86 
 87 CodeletMark::CodeletMark(InterpreterMacroAssembler*& masm,
 88                          const char* description,
 89                          Bytecodes::Code bytecode) :
 90   _clet((InterpreterCodelet*)AbstractInterpreter::code()->request(codelet_size())),
 91   _cb(_clet->code_begin(), _clet->code_size()) {
 92   // Request all space (add some slack for Codelet data).
 93   assert(_clet != NULL, "we checked not enough space already");
 94 
 95   // Initialize Codelet attributes.
 96   _clet->initialize(description, bytecode);
 97   // Create assembler for code generation.
 98   masm = new InterpreterMacroAssembler(&_cb);
 99   _masm = &masm;
100 }
101 
102 CodeletMark::~CodeletMark() {
103   // Align so printing shows nop's instead of random code at the end (Codelets are aligned).
104   (*_masm)->align(wordSize);
105   // Make sure all code is in code buffer.
106   (*_masm)->flush();
107 
108   // Commit Codelet.
109   int committed_code_size = (*_masm)->code()->pure_insts_size();
110   if (committed_code_size > 0) {
111     // This is  the ONE place where  we pickup any assembly  remarks and debug
112     // strings, and propagate these to the codelet.
113     NOT_PRODUCT(_clet->use_remarks((*_masm)->code()->asm_remarks()));
114     NOT_PRODUCT(_clet->use_strings((*_masm)->code()->dbg_strings()));
115 
116     AbstractInterpreter::code()->commit(committed_code_size);
117   }
118   // Make sure nobody can use _masm outside a CodeletMark lifespan.
119   *_masm = NULL;
120 }
121 
122 // The reason that interpreter initialization is split into two parts is that the first part
123 // needs to run before methods are loaded (which with CDS implies linked also), and the other
124 // part needs to run after. The reason is that when methods are loaded (with CDS) or linked
125 // (without CDS), the i2c adapters are generated that assert we are currently in the interpreter.
126 // Asserting that requires knowledge about where the interpreter is in memory. Therefore,
127 // establishing the interpreter address must be done before methods are loaded. However,
128 // we would like to actually generate the interpreter after methods are loaded. That allows
129 // us to remove otherwise hardcoded offsets regarding fields that are needed in the interpreter
130 // code. This leads to a split if 1. reserving the memory for the interpreter, 2. loading methods
131 // and 3. generating the interpreter.
132 void interpreter_init_stub() {
133   Interpreter::initialize_stub();
134 }
135 
136 void interpreter_init_code() {
137   Interpreter::initialize_code();
138 #ifndef PRODUCT
139   if (TraceBytecodes) BytecodeTracer::set_closure(BytecodeTracer::std_closure());
140 #endif // PRODUCT
141   // need to hit every safepoint in order to call zapping routine
142   // register the interpreter
143   Forte::register_stub(
144     "Interpreter",
145     AbstractInterpreter::code()->code_start(),
146     AbstractInterpreter::code()->code_end()
147   );
148 
149   // notify JVMTI profiler
150   if (JvmtiExport::should_post_dynamic_code_generated()) {
151     JvmtiExport::post_dynamic_code_generated("Interpreter",
152                                              AbstractInterpreter::code()->code_start(),
153                                              AbstractInterpreter::code()->code_end());
154   }
155 }