| 1 | /* | 
|---|
| 2 | * Copyright (c) 1997, 2017, 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 "ci/ciMethod.hpp" | 
|---|
| 27 | #include "interpreter/interpreter.hpp" | 
|---|
| 28 | #include "runtime/frame.inline.hpp" | 
|---|
| 29 |  | 
|---|
| 30 |  | 
|---|
| 31 | // asm based interpreter deoptimization helpers | 
|---|
| 32 | int AbstractInterpreter::size_activation(int max_stack, | 
|---|
| 33 | int temps, | 
|---|
| 34 | int , | 
|---|
| 35 | int monitors, | 
|---|
| 36 | int callee_params, | 
|---|
| 37 | int callee_locals, | 
|---|
| 38 | bool is_top_frame) { | 
|---|
| 39 | // Note: This calculation must exactly parallel the frame setup | 
|---|
| 40 | // in TemplateInterpreterGenerator::generate_fixed_frame. | 
|---|
| 41 |  | 
|---|
| 42 | // fixed size of an interpreter frame: | 
|---|
| 43 | int overhead = frame::sender_sp_offset - | 
|---|
| 44 | frame::interpreter_frame_initial_sp_offset; | 
|---|
| 45 | // Our locals were accounted for by the caller (or last_frame_adjust | 
|---|
| 46 | // on the transistion) Since the callee parameters already account | 
|---|
| 47 | // for the callee's params we only need to account for the extra | 
|---|
| 48 | // locals. | 
|---|
| 49 | int size = overhead + | 
|---|
| 50 | (callee_locals - callee_params)*Interpreter::stackElementWords + | 
|---|
| 51 | monitors * frame::interpreter_frame_monitor_size() + | 
|---|
| 52 | temps* Interpreter::stackElementWords + extra_args; | 
|---|
| 53 |  | 
|---|
| 54 | return size; | 
|---|
| 55 | } | 
|---|
| 56 |  | 
|---|
| 57 | void AbstractInterpreter::layout_activation(Method* method, | 
|---|
| 58 | int tempcount, | 
|---|
| 59 | int , | 
|---|
| 60 | int moncount, | 
|---|
| 61 | int caller_actual_parameters, | 
|---|
| 62 | int callee_param_count, | 
|---|
| 63 | int callee_locals, | 
|---|
| 64 | frame* caller, | 
|---|
| 65 | frame* interpreter_frame, | 
|---|
| 66 | bool is_top_frame, | 
|---|
| 67 | bool is_bottom_frame) { | 
|---|
| 68 | // The frame interpreter_frame is guaranteed to be the right size, | 
|---|
| 69 | // as determined by a previous call to the size_activation() method. | 
|---|
| 70 | // It is also guaranteed to be walkable even though it is in a | 
|---|
| 71 | // skeletal state | 
|---|
| 72 |  | 
|---|
| 73 | int max_locals = method->max_locals() * Interpreter::stackElementWords; | 
|---|
| 74 | int  = (method->max_locals() - method->size_of_parameters()) * | 
|---|
| 75 | Interpreter::stackElementWords; | 
|---|
| 76 |  | 
|---|
| 77 | #ifdef ASSERT | 
|---|
| 78 | assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable"); | 
|---|
| 79 | #endif | 
|---|
| 80 |  | 
|---|
| 81 | interpreter_frame->interpreter_frame_set_method(method); | 
|---|
| 82 | // NOTE the difference in using sender_sp and | 
|---|
| 83 | // interpreter_frame_sender_sp interpreter_frame_sender_sp is | 
|---|
| 84 | // the original sp of the caller (the unextended_sp) and | 
|---|
| 85 | // sender_sp is fp+8/16 (32bit/64bit) XXX | 
|---|
| 86 | intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; | 
|---|
| 87 |  | 
|---|
| 88 | #ifdef ASSERT | 
|---|
| 89 | if (caller->is_interpreted_frame()) { | 
|---|
| 90 | assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); | 
|---|
| 91 | } | 
|---|
| 92 | #endif | 
|---|
| 93 |  | 
|---|
| 94 | interpreter_frame->interpreter_frame_set_locals(locals); | 
|---|
| 95 | BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); | 
|---|
| 96 | BasicObjectLock* monbot = montop - moncount; | 
|---|
| 97 | interpreter_frame->interpreter_frame_set_monitor_end(monbot); | 
|---|
| 98 |  | 
|---|
| 99 | // Set last_sp | 
|---|
| 100 | intptr_t*  esp = (intptr_t*) monbot - | 
|---|
| 101 | tempcount*Interpreter::stackElementWords - | 
|---|
| 102 | popframe_extra_args; | 
|---|
| 103 | interpreter_frame->interpreter_frame_set_last_sp(esp); | 
|---|
| 104 |  | 
|---|
| 105 | // All frames but the initial (oldest) interpreter frame we fill in have | 
|---|
| 106 | // a value for sender_sp that allows walking the stack but isn't | 
|---|
| 107 | // truly correct. Correct the value here. | 
|---|
| 108 | if (extra_locals != 0 && | 
|---|
| 109 | interpreter_frame->sender_sp() == | 
|---|
| 110 | interpreter_frame->interpreter_frame_sender_sp()) { | 
|---|
| 111 | interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + | 
|---|
| 112 | extra_locals); | 
|---|
| 113 | } | 
|---|
| 114 | *interpreter_frame->interpreter_frame_cache_addr() = | 
|---|
| 115 | method->constants()->cache(); | 
|---|
| 116 | *interpreter_frame->interpreter_frame_mirror_addr() = | 
|---|
| 117 | method->method_holder()->java_mirror(); | 
|---|
| 118 | } | 
|---|
| 119 |  | 
|---|
| 120 | #ifndef _LP64 | 
|---|
| 121 | int AbstractInterpreter::BasicType_as_index(BasicType type) { | 
|---|
| 122 | int i = 0; | 
|---|
| 123 | switch (type) { | 
|---|
| 124 | case T_BOOLEAN: i = 0; break; | 
|---|
| 125 | case T_CHAR   : i = 1; break; | 
|---|
| 126 | case T_BYTE   : i = 2; break; | 
|---|
| 127 | case T_SHORT  : i = 3; break; | 
|---|
| 128 | case T_INT    : // fall through | 
|---|
| 129 | case T_LONG   : // fall through | 
|---|
| 130 | case T_VOID   : i = 4; break; | 
|---|
| 131 | case T_FLOAT  : i = 5; break;  // have to treat float and double separately for SSE | 
|---|
| 132 | case T_DOUBLE : i = 6; break; | 
|---|
| 133 | case T_OBJECT : // fall through | 
|---|
| 134 | case T_ARRAY  : i = 7; break; | 
|---|
| 135 | default       : ShouldNotReachHere(); | 
|---|
| 136 | } | 
|---|
| 137 | assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds"); | 
|---|
| 138 | return i; | 
|---|
| 139 | } | 
|---|
| 140 | #else | 
|---|
| 141 | int AbstractInterpreter::BasicType_as_index(BasicType type) { | 
|---|
| 142 | int i = 0; | 
|---|
| 143 | switch (type) { | 
|---|
| 144 | case T_BOOLEAN: i = 0; break; | 
|---|
| 145 | case T_CHAR   : i = 1; break; | 
|---|
| 146 | case T_BYTE   : i = 2; break; | 
|---|
| 147 | case T_SHORT  : i = 3; break; | 
|---|
| 148 | case T_INT    : i = 4; break; | 
|---|
| 149 | case T_LONG   : i = 5; break; | 
|---|
| 150 | case T_VOID   : i = 6; break; | 
|---|
| 151 | case T_FLOAT  : i = 7; break; | 
|---|
| 152 | case T_DOUBLE : i = 8; break; | 
|---|
| 153 | case T_OBJECT : i = 9; break; | 
|---|
| 154 | case T_ARRAY  : i = 9; break; | 
|---|
| 155 | default       : ShouldNotReachHere(); | 
|---|
| 156 | } | 
|---|
| 157 | assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, | 
|---|
| 158 | "index out of bounds"); | 
|---|
| 159 | return i; | 
|---|
| 160 | } | 
|---|
| 161 | #endif // _LP64 | 
|---|
| 162 |  | 
|---|
| 163 | // How much stack a method activation needs in words. | 
|---|
| 164 | int AbstractInterpreter::size_top_interpreter_activation(Method* method) { | 
|---|
| 165 | const int entry_size = frame::interpreter_frame_monitor_size(); | 
|---|
| 166 |  | 
|---|
| 167 | // total overhead size: entry_size + (saved rbp thru expr stack | 
|---|
| 168 | // bottom).  be sure to change this if you add/subtract anything | 
|---|
| 169 | // to/from the overhead area | 
|---|
| 170 | const int overhead_size = | 
|---|
| 171 | -(frame::interpreter_frame_initial_sp_offset) + entry_size; | 
|---|
| 172 |  | 
|---|
| 173 | #ifndef _LP64 | 
|---|
| 174 | const int stub_code = 4;  // see generate_call_stub | 
|---|
| 175 | #else | 
|---|
| 176 | const int stub_code = frame::entry_frame_after_call_words; | 
|---|
| 177 | #endif | 
|---|
| 178 |  | 
|---|
| 179 | const int method_stack = (method->max_locals() + method->max_stack()) * | 
|---|
| 180 | Interpreter::stackElementWords; | 
|---|
| 181 | return (overhead_size + method_stack + stub_code); | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|