Mercurial > hg > truffle
comparison src/cpu/ppc/vm/frame_ppc.inline.hpp @ 14408:ec28f9c041ff
8019972: PPC64 (part 9): platform files for interpreter only VM.
Summary: With this change the HotSpot core build works on Linux/PPC64. The VM succesfully executes simple test programs.
Reviewed-by: kvn
author | goetz |
---|---|
date | Fri, 02 Aug 2013 16:46:45 +0200 |
parents | |
children | 67fa91961822 |
comparison
equal
deleted
inserted
replaced
14407:94c202aa2646 | 14408:ec28f9c041ff |
---|---|
1 /* | |
2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. | |
3 * Copyright 2012, 2013 SAP AG. All rights reserved. | |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
26 #ifndef CPU_PPC_VM_FRAME_PPC_INLINE_HPP | |
27 #define CPU_PPC_VM_FRAME_PPC_INLINE_HPP | |
28 | |
29 #ifndef CC_INTERP | |
30 #error "CC_INTERP must be defined on PPC64" | |
31 #endif | |
32 | |
33 // Inline functions for ppc64 frames: | |
34 | |
35 // Find codeblob and set deopt_state. | |
36 inline void frame::find_codeblob_and_set_pc_and_deopt_state(address pc) { | |
37 assert(pc != NULL, "precondition: must have PC"); | |
38 | |
39 _cb = CodeCache::find_blob(pc); | |
40 _pc = pc; // Must be set for get_deopt_original_pc() | |
41 | |
42 _fp = (intptr_t*)own_abi()->callers_sp; | |
43 // Use _fp - frame_size, needs to be done between _cb and _pc initialization | |
44 // and get_deopt_original_pc. | |
45 adjust_unextended_sp(); | |
46 | |
47 address original_pc = nmethod::get_deopt_original_pc(this); | |
48 if (original_pc != NULL) { | |
49 _pc = original_pc; | |
50 _deopt_state = is_deoptimized; | |
51 } else { | |
52 _deopt_state = not_deoptimized; | |
53 } | |
54 | |
55 assert(((uint64_t)_sp & 0xf) == 0, "SP must be 16-byte aligned"); | |
56 } | |
57 | |
58 // Constructors | |
59 | |
60 // Initialize all fields, _unextended_sp will be adjusted in find_codeblob_and_set_pc_and_deopt_state. | |
61 inline frame::frame() : _sp(NULL), _unextended_sp(NULL), _fp(NULL), _cb(NULL), _pc(NULL), _deopt_state(unknown) {} | |
62 | |
63 inline frame::frame(intptr_t* sp) : _sp(sp), _unextended_sp(sp) { | |
64 find_codeblob_and_set_pc_and_deopt_state((address)own_abi()->lr); // also sets _fp and adjusts _unextended_sp | |
65 } | |
66 | |
67 inline frame::frame(intptr_t* sp, address pc) : _sp(sp), _unextended_sp(sp) { | |
68 find_codeblob_and_set_pc_and_deopt_state(pc); // also sets _fp and adjusts _unextended_sp | |
69 } | |
70 | |
71 inline frame::frame(intptr_t* sp, address pc, intptr_t* unextended_sp) : _sp(sp), _unextended_sp(unextended_sp) { | |
72 find_codeblob_and_set_pc_and_deopt_state(pc); // also sets _fp and adjusts _unextended_sp | |
73 } | |
74 | |
75 // Accessors | |
76 | |
77 // Return unique id for this frame. The id must have a value where we | |
78 // can distinguish identity and younger/older relationship. NULL | |
79 // represents an invalid (incomparable) frame. | |
80 inline intptr_t* frame::id(void) const { | |
81 // Use the _unextended_pc as the frame's ID. Because we have no | |
82 // adapters, but resized compiled frames, some of the new code | |
83 // (e.g. JVMTI) wouldn't work if we return the (current) SP of the | |
84 // frame. | |
85 return _unextended_sp; | |
86 } | |
87 | |
88 // Return true if this frame is older (less recent activation) than | |
89 // the frame represented by id. | |
90 inline bool frame::is_older(intptr_t* id) const { | |
91 assert(this->id() != NULL && id != NULL, "NULL frame id"); | |
92 // Stack grows towards smaller addresses on ppc64. | |
93 return this->id() > id; | |
94 } | |
95 | |
96 inline int frame::frame_size(RegisterMap* map) const { | |
97 // Stack grows towards smaller addresses on PPC64: sender is at a higher address. | |
98 return sender_sp() - sp(); | |
99 } | |
100 | |
101 // Return the frame's stack pointer before it has been extended by a | |
102 // c2i adapter. This is needed by deoptimization for ignoring c2i adapter | |
103 // frames. | |
104 inline intptr_t* frame::unextended_sp() const { | |
105 return _unextended_sp; | |
106 } | |
107 | |
108 // All frames have this field. | |
109 inline address frame::sender_pc() const { | |
110 return (address)callers_abi()->lr; | |
111 } | |
112 inline address* frame::sender_pc_addr() const { | |
113 return (address*)&(callers_abi()->lr); | |
114 } | |
115 | |
116 // All frames have this field. | |
117 inline intptr_t* frame::sender_sp() const { | |
118 return (intptr_t*)callers_abi(); | |
119 } | |
120 | |
121 // All frames have this field. | |
122 inline intptr_t* frame::link() const { | |
123 return (intptr_t*)callers_abi()->callers_sp; | |
124 } | |
125 | |
126 inline intptr_t* frame::real_fp() const { | |
127 return fp(); | |
128 } | |
129 | |
130 #ifdef CC_INTERP | |
131 | |
132 inline interpreterState frame::get_interpreterState() const { | |
133 return (interpreterState)(((address)callers_abi()) | |
134 - frame::interpreter_frame_cinterpreterstate_size_in_bytes()); | |
135 } | |
136 | |
137 inline intptr_t** frame::interpreter_frame_locals_addr() const { | |
138 interpreterState istate = get_interpreterState(); | |
139 return (intptr_t**)&istate->_locals; | |
140 } | |
141 | |
142 inline intptr_t* frame::interpreter_frame_bcx_addr() const { | |
143 interpreterState istate = get_interpreterState(); | |
144 return (intptr_t*)&istate->_bcp; | |
145 } | |
146 | |
147 inline intptr_t* frame::interpreter_frame_mdx_addr() const { | |
148 interpreterState istate = get_interpreterState(); | |
149 return (intptr_t*)&istate->_mdx; | |
150 } | |
151 | |
152 inline intptr_t* frame::interpreter_frame_expression_stack() const { | |
153 return (intptr_t*)interpreter_frame_monitor_end() - 1; | |
154 } | |
155 | |
156 inline jint frame::interpreter_frame_expression_stack_direction() { | |
157 return -1; | |
158 } | |
159 | |
160 // top of expression stack | |
161 inline intptr_t* frame::interpreter_frame_tos_address() const { | |
162 interpreterState istate = get_interpreterState(); | |
163 return istate->_stack + 1; | |
164 } | |
165 | |
166 inline intptr_t* frame::interpreter_frame_tos_at(jint offset) const { | |
167 return &interpreter_frame_tos_address()[offset]; | |
168 } | |
169 | |
170 // monitor elements | |
171 | |
172 // in keeping with Intel side: end is lower in memory than begin; | |
173 // and beginning element is oldest element | |
174 // Also begin is one past last monitor. | |
175 | |
176 inline BasicObjectLock* frame::interpreter_frame_monitor_begin() const { | |
177 return get_interpreterState()->monitor_base(); | |
178 } | |
179 | |
180 inline BasicObjectLock* frame::interpreter_frame_monitor_end() const { | |
181 return (BasicObjectLock*)get_interpreterState()->stack_base(); | |
182 } | |
183 | |
184 inline int frame::interpreter_frame_cinterpreterstate_size_in_bytes() { | |
185 // Size of an interpreter object. Not aligned with frame size. | |
186 return round_to(sizeof(BytecodeInterpreter), 8); | |
187 } | |
188 | |
189 inline Method** frame::interpreter_frame_method_addr() const { | |
190 interpreterState istate = get_interpreterState(); | |
191 return &istate->_method; | |
192 } | |
193 | |
194 // Constant pool cache | |
195 | |
196 inline ConstantPoolCache** frame::interpreter_frame_cpoolcache_addr() const { | |
197 interpreterState istate = get_interpreterState(); | |
198 return &istate->_constants; // should really use accessor | |
199 } | |
200 | |
201 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const { | |
202 interpreterState istate = get_interpreterState(); | |
203 return &istate->_constants; | |
204 } | |
205 #endif // CC_INTERP | |
206 | |
207 inline int frame::interpreter_frame_monitor_size() { | |
208 // Number of stack slots for a monitor. | |
209 return round_to(BasicObjectLock::size(), // number of stack slots | |
210 WordsPerLong); // number of stack slots for a Java long | |
211 } | |
212 | |
213 inline int frame::interpreter_frame_monitor_size_in_bytes() { | |
214 return frame::interpreter_frame_monitor_size() * wordSize; | |
215 } | |
216 | |
217 // entry frames | |
218 | |
219 inline intptr_t* frame::entry_frame_argument_at(int offset) const { | |
220 // Since an entry frame always calls the interpreter first, the | |
221 // parameters are on the stack and relative to known register in the | |
222 // entry frame. | |
223 intptr_t* tos = (intptr_t*)get_entry_frame_locals()->arguments_tos_address; | |
224 return &tos[offset + 1]; // prepushed tos | |
225 } | |
226 | |
227 inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { | |
228 return (JavaCallWrapper**)&get_entry_frame_locals()->call_wrapper_address; | |
229 } | |
230 | |
231 inline oop frame::saved_oop_result(RegisterMap* map) const { | |
232 return *((oop*)map->location(R3->as_VMReg())); | |
233 } | |
234 | |
235 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { | |
236 *((oop*)map->location(R3->as_VMReg())) = obj; | |
237 } | |
238 | |
239 #endif // CPU_PPC_VM_FRAME_PPC_INLINE_HPP |