1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/sparc/vm/frame_sparc.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,606 @@ 1.4 +/* 1.5 + * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_frame_sparc.cpp.incl" 1.30 + 1.31 +void RegisterMap::pd_clear() { 1.32 + if (_thread->has_last_Java_frame()) { 1.33 + frame fr = _thread->last_frame(); 1.34 + _window = fr.sp(); 1.35 + } else { 1.36 + _window = NULL; 1.37 + } 1.38 + _younger_window = NULL; 1.39 +} 1.40 + 1.41 + 1.42 +// Unified register numbering scheme: each 32-bits counts as a register 1.43 +// number, so all the V9 registers take 2 slots. 1.44 +const static int R_L_nums[] = {0+040,2+040,4+040,6+040,8+040,10+040,12+040,14+040}; 1.45 +const static int R_I_nums[] = {0+060,2+060,4+060,6+060,8+060,10+060,12+060,14+060}; 1.46 +const static int R_O_nums[] = {0+020,2+020,4+020,6+020,8+020,10+020,12+020,14+020}; 1.47 +const static int R_G_nums[] = {0+000,2+000,4+000,6+000,8+000,10+000,12+000,14+000}; 1.48 +static RegisterMap::LocationValidType bad_mask = 0; 1.49 +static RegisterMap::LocationValidType R_LIO_mask = 0; 1.50 +static bool register_map_inited = false; 1.51 + 1.52 +static void register_map_init() { 1.53 + if (!register_map_inited) { 1.54 + register_map_inited = true; 1.55 + int i; 1.56 + for (i = 0; i < 8; i++) { 1.57 + assert(R_L_nums[i] < RegisterMap::location_valid_type_size, "in first chunk"); 1.58 + assert(R_I_nums[i] < RegisterMap::location_valid_type_size, "in first chunk"); 1.59 + assert(R_O_nums[i] < RegisterMap::location_valid_type_size, "in first chunk"); 1.60 + assert(R_G_nums[i] < RegisterMap::location_valid_type_size, "in first chunk"); 1.61 + } 1.62 + 1.63 + bad_mask |= (1LL << R_O_nums[6]); // SP 1.64 + bad_mask |= (1LL << R_O_nums[7]); // cPC 1.65 + bad_mask |= (1LL << R_I_nums[6]); // FP 1.66 + bad_mask |= (1LL << R_I_nums[7]); // rPC 1.67 + bad_mask |= (1LL << R_G_nums[2]); // TLS 1.68 + bad_mask |= (1LL << R_G_nums[7]); // reserved by libthread 1.69 + 1.70 + for (i = 0; i < 8; i++) { 1.71 + R_LIO_mask |= (1LL << R_L_nums[i]); 1.72 + R_LIO_mask |= (1LL << R_I_nums[i]); 1.73 + R_LIO_mask |= (1LL << R_O_nums[i]); 1.74 + } 1.75 + } 1.76 +} 1.77 + 1.78 + 1.79 +address RegisterMap::pd_location(VMReg regname) const { 1.80 + register_map_init(); 1.81 + 1.82 + assert(regname->is_reg(), "sanity check"); 1.83 + // Only the GPRs get handled this way 1.84 + if( !regname->is_Register()) 1.85 + return NULL; 1.86 + 1.87 + // don't talk about bad registers 1.88 + if ((bad_mask & ((LocationValidType)1 << regname->value())) != 0) { 1.89 + return NULL; 1.90 + } 1.91 + 1.92 + // Convert to a GPR 1.93 + Register reg; 1.94 + int second_word = 0; 1.95 + // 32-bit registers for in, out and local 1.96 + if (!regname->is_concrete()) { 1.97 + // HMM ought to return NULL for any non-concrete (odd) vmreg 1.98 + // this all tied up in the fact we put out double oopMaps for 1.99 + // register locations. When that is fixed we'd will return NULL 1.100 + // (or assert here). 1.101 + reg = regname->prev()->as_Register(); 1.102 +#ifdef _LP64 1.103 + second_word = sizeof(jint); 1.104 +#else 1.105 + return NULL; 1.106 +#endif // _LP64 1.107 + } else { 1.108 + reg = regname->as_Register(); 1.109 + } 1.110 + if (reg->is_out()) { 1.111 + assert(_younger_window != NULL, "Younger window should be available"); 1.112 + return second_word + (address)&_younger_window[reg->after_save()->sp_offset_in_saved_window()]; 1.113 + } 1.114 + if (reg->is_local() || reg->is_in()) { 1.115 + assert(_window != NULL, "Window should be available"); 1.116 + return second_word + (address)&_window[reg->sp_offset_in_saved_window()]; 1.117 + } 1.118 + // Only the window'd GPRs get handled this way; not the globals. 1.119 + return NULL; 1.120 +} 1.121 + 1.122 + 1.123 +#ifdef ASSERT 1.124 +void RegisterMap::check_location_valid() { 1.125 + register_map_init(); 1.126 + assert((_location_valid[0] & bad_mask) == 0, "cannot have special locations for SP,FP,TLS,etc."); 1.127 +} 1.128 +#endif 1.129 + 1.130 +// We are shifting windows. That means we are moving all %i to %o, 1.131 +// getting rid of all current %l, and keeping all %g. This is only 1.132 +// complicated if any of the location pointers for these are valid. 1.133 +// The normal case is that everything is in its standard register window 1.134 +// home, and _location_valid[0] is zero. In that case, this routine 1.135 +// does exactly nothing. 1.136 +void RegisterMap::shift_individual_registers() { 1.137 + if (!update_map()) return; // this only applies to maps with locations 1.138 + register_map_init(); 1.139 + check_location_valid(); 1.140 + 1.141 + LocationValidType lv = _location_valid[0]; 1.142 + LocationValidType lv0 = lv; 1.143 + 1.144 + lv &= ~R_LIO_mask; // clear %l, %o, %i regs 1.145 + 1.146 + // if we cleared some non-%g locations, we may have to do some shifting 1.147 + if (lv != lv0) { 1.148 + // copy %i0-%i5 to %o0-%o5, if they have special locations 1.149 + // This can happen in within stubs which spill argument registers 1.150 + // around a dynamic link operation, such as resolve_opt_virtual_call. 1.151 + for (int i = 0; i < 8; i++) { 1.152 + if (lv0 & (1LL << R_I_nums[i])) { 1.153 + _location[R_O_nums[i]] = _location[R_I_nums[i]]; 1.154 + lv |= (1LL << R_O_nums[i]); 1.155 + } 1.156 + } 1.157 + } 1.158 + 1.159 + _location_valid[0] = lv; 1.160 + check_location_valid(); 1.161 +} 1.162 + 1.163 + 1.164 +bool frame::safe_for_sender(JavaThread *thread) { 1.165 + address sp = (address)_sp; 1.166 + if (sp != NULL && 1.167 + (sp <= thread->stack_base() && sp >= thread->stack_base() - thread->stack_size())) { 1.168 + // Unfortunately we can only check frame complete for runtime stubs and nmethod 1.169 + // other generic buffer blobs are more problematic so we just assume they are 1.170 + // ok. adapter blobs never have a frame complete and are never ok. 1.171 + if (_cb != NULL && !_cb->is_frame_complete_at(_pc)) { 1.172 + if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { 1.173 + return false; 1.174 + } 1.175 + } 1.176 + return true; 1.177 + } 1.178 + return false; 1.179 +} 1.180 + 1.181 +// constructors 1.182 + 1.183 +// Construct an unpatchable, deficient frame 1.184 +frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) { 1.185 +#ifdef _LP64 1.186 + assert( (((intptr_t)sp & (wordSize-1)) == 0), "frame constructor passed an invalid sp"); 1.187 +#endif 1.188 + _sp = sp; 1.189 + _younger_sp = NULL; 1.190 + _pc = pc; 1.191 + _cb = cb; 1.192 + _sp_adjustment_by_callee = 0; 1.193 + assert(pc == NULL && cb == NULL || pc != NULL, "can't have a cb and no pc!"); 1.194 + if (_cb == NULL && _pc != NULL ) { 1.195 + _cb = CodeCache::find_blob(_pc); 1.196 + } 1.197 + _deopt_state = unknown; 1.198 +#ifdef ASSERT 1.199 + if ( _cb != NULL && _cb->is_nmethod()) { 1.200 + // Without a valid unextended_sp() we can't convert the pc to "original" 1.201 + assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant broken"); 1.202 + } 1.203 +#endif // ASSERT 1.204 +} 1.205 + 1.206 +frame::frame(intptr_t* sp, intptr_t* younger_sp, bool younger_frame_adjusted_stack) { 1.207 + _sp = sp; 1.208 + _younger_sp = younger_sp; 1.209 + if (younger_sp == NULL) { 1.210 + // make a deficient frame which doesn't know where its PC is 1.211 + _pc = NULL; 1.212 + _cb = NULL; 1.213 + } else { 1.214 + _pc = (address)younger_sp[I7->sp_offset_in_saved_window()] + pc_return_offset; 1.215 + assert( (intptr_t*)younger_sp[FP->sp_offset_in_saved_window()] == (intptr_t*)((intptr_t)sp - STACK_BIAS), "younger_sp must be valid"); 1.216 + // Any frame we ever build should always "safe" therefore we should not have to call 1.217 + // find_blob_unsafe 1.218 + // In case of native stubs, the pc retrieved here might be 1.219 + // wrong. (the _last_native_pc will have the right value) 1.220 + // So do not put add any asserts on the _pc here. 1.221 + } 1.222 + if (younger_frame_adjusted_stack) { 1.223 + // compute adjustment to this frame's SP made by its interpreted callee 1.224 + _sp_adjustment_by_callee = (intptr_t*)((intptr_t)younger_sp[I5_savedSP->sp_offset_in_saved_window()] + 1.225 + STACK_BIAS) - sp; 1.226 + } else { 1.227 + _sp_adjustment_by_callee = 0; 1.228 + } 1.229 + 1.230 + _deopt_state = unknown; 1.231 + 1.232 + // It is important that frame be fully construct when we do this lookup 1.233 + // as get_original_pc() needs correct value for unextended_sp() 1.234 + if (_pc != NULL) { 1.235 + _cb = CodeCache::find_blob(_pc); 1.236 + if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 1.237 + _pc = ((nmethod*)_cb)->get_original_pc(this); 1.238 + _deopt_state = is_deoptimized; 1.239 + } else { 1.240 + _deopt_state = not_deoptimized; 1.241 + } 1.242 + } 1.243 +} 1.244 + 1.245 +bool frame::is_interpreted_frame() const { 1.246 + return Interpreter::contains(pc()); 1.247 +} 1.248 + 1.249 +// sender_sp 1.250 + 1.251 +intptr_t* frame::interpreter_frame_sender_sp() const { 1.252 + assert(is_interpreted_frame(), "interpreted frame expected"); 1.253 + return fp(); 1.254 +} 1.255 + 1.256 +#ifndef CC_INTERP 1.257 +void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) { 1.258 + assert(is_interpreted_frame(), "interpreted frame expected"); 1.259 + Unimplemented(); 1.260 +} 1.261 +#endif // CC_INTERP 1.262 + 1.263 + 1.264 +#ifdef ASSERT 1.265 +// Debugging aid 1.266 +static frame nth_sender(int n) { 1.267 + frame f = JavaThread::current()->last_frame(); 1.268 + 1.269 + for(int i = 0; i < n; ++i) 1.270 + f = f.sender((RegisterMap*)NULL); 1.271 + 1.272 + printf("first frame %d\n", f.is_first_frame() ? 1 : 0); 1.273 + printf("interpreted frame %d\n", f.is_interpreted_frame() ? 1 : 0); 1.274 + printf("java frame %d\n", f.is_java_frame() ? 1 : 0); 1.275 + printf("entry frame %d\n", f.is_entry_frame() ? 1 : 0); 1.276 + printf("native frame %d\n", f.is_native_frame() ? 1 : 0); 1.277 + if (f.is_compiled_frame()) { 1.278 + if (f.is_deoptimized_frame()) 1.279 + printf("deoptimized frame 1\n"); 1.280 + else 1.281 + printf("compiled frame 1\n"); 1.282 + } 1.283 + 1.284 + return f; 1.285 +} 1.286 +#endif 1.287 + 1.288 + 1.289 +frame frame::sender_for_entry_frame(RegisterMap *map) const { 1.290 + assert(map != NULL, "map must be set"); 1.291 + // Java frame called from C; skip all C frames and return top C 1.292 + // frame of that chunk as the sender 1.293 + JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); 1.294 + assert(!entry_frame_is_first(), "next Java fp must be non zero"); 1.295 + assert(jfa->last_Java_sp() > _sp, "must be above this frame on stack"); 1.296 + intptr_t* last_Java_sp = jfa->last_Java_sp(); 1.297 + // Since we are walking the stack now this nested anchor is obviously walkable 1.298 + // even if it wasn't when it was stacked. 1.299 + if (!jfa->walkable()) { 1.300 + // Capture _last_Java_pc (if needed) and mark anchor walkable. 1.301 + jfa->capture_last_Java_pc(_sp); 1.302 + } 1.303 + assert(jfa->last_Java_pc() != NULL, "No captured pc!"); 1.304 + map->clear(); 1.305 + map->make_integer_regs_unsaved(); 1.306 + map->shift_window(last_Java_sp, NULL); 1.307 + assert(map->include_argument_oops(), "should be set by clear"); 1.308 + return frame(last_Java_sp, frame::unpatchable, jfa->last_Java_pc()); 1.309 +} 1.310 + 1.311 +frame frame::sender_for_interpreter_frame(RegisterMap *map) const { 1.312 + ShouldNotCallThis(); 1.313 + return sender(map); 1.314 +} 1.315 + 1.316 +frame frame::sender_for_compiled_frame(RegisterMap *map) const { 1.317 + ShouldNotCallThis(); 1.318 + return sender(map); 1.319 +} 1.320 + 1.321 +frame frame::sender(RegisterMap* map) const { 1.322 + assert(map != NULL, "map must be set"); 1.323 + 1.324 + assert(CodeCache::find_blob_unsafe(_pc) == _cb, "inconsistent"); 1.325 + 1.326 + // Default is not to follow arguments; update it accordingly below 1.327 + map->set_include_argument_oops(false); 1.328 + 1.329 + if (is_entry_frame()) return sender_for_entry_frame(map); 1.330 + 1.331 + intptr_t* younger_sp = sp(); 1.332 + intptr_t* sp = sender_sp(); 1.333 + bool adjusted_stack = false; 1.334 + 1.335 + // Note: The version of this operation on any platform with callee-save 1.336 + // registers must update the register map (if not null). 1.337 + // In order to do this correctly, the various subtypes of 1.338 + // of frame (interpreted, compiled, glue, native), 1.339 + // must be distinguished. There is no need on SPARC for 1.340 + // such distinctions, because all callee-save registers are 1.341 + // preserved for all frames via SPARC-specific mechanisms. 1.342 + // 1.343 + // *** HOWEVER, *** if and when we make any floating-point 1.344 + // registers callee-saved, then we will have to copy over 1.345 + // the RegisterMap update logic from the Intel code. 1.346 + 1.347 + // The constructor of the sender must know whether this frame is interpreted so it can set the 1.348 + // sender's _sp_adjustment_by_callee field. An osr adapter frame was originally 1.349 + // interpreted but its pc is in the code cache (for c1 -> osr_frame_return_id stub), so it must be 1.350 + // explicitly recognized. 1.351 + 1.352 + adjusted_stack = is_interpreted_frame(); 1.353 + if (adjusted_stack) { 1.354 + map->make_integer_regs_unsaved(); 1.355 + map->shift_window(sp, younger_sp); 1.356 + } else if (_cb != NULL) { 1.357 + // Update the locations of implicitly saved registers to be their 1.358 + // addresses in the register save area. 1.359 + // For %o registers, the addresses of %i registers in the next younger 1.360 + // frame are used. 1.361 + map->shift_window(sp, younger_sp); 1.362 + if (map->update_map()) { 1.363 + // Tell GC to use argument oopmaps for some runtime stubs that need it. 1.364 + // For C1, the runtime stub might not have oop maps, so set this flag 1.365 + // outside of update_register_map. 1.366 + map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread())); 1.367 + if (_cb->oop_maps() != NULL) { 1.368 + OopMapSet::update_register_map(this, map); 1.369 + } 1.370 + } 1.371 + } 1.372 + return frame(sp, younger_sp, adjusted_stack); 1.373 +} 1.374 + 1.375 + 1.376 +void frame::patch_pc(Thread* thread, address pc) { 1.377 + if(thread == Thread::current()) { 1.378 + StubRoutines::Sparc::flush_callers_register_windows_func()(); 1.379 + } 1.380 + if (TracePcPatching) { 1.381 + // QQQ this assert is invalid (or too strong anyway) sice _pc could 1.382 + // be original pc and frame could have the deopt pc. 1.383 + // assert(_pc == *O7_addr() + pc_return_offset, "frame has wrong pc"); 1.384 + tty->print_cr("patch_pc at address 0x%x [0x%x -> 0x%x] ", O7_addr(), _pc, pc); 1.385 + } 1.386 + _cb = CodeCache::find_blob(pc); 1.387 + *O7_addr() = pc - pc_return_offset; 1.388 + _cb = CodeCache::find_blob(_pc); 1.389 + if (_cb != NULL && _cb->is_nmethod() && ((nmethod*)_cb)->is_deopt_pc(_pc)) { 1.390 + address orig = ((nmethod*)_cb)->get_original_pc(this); 1.391 + assert(orig == _pc, "expected original to be stored before patching"); 1.392 + _deopt_state = is_deoptimized; 1.393 + } else { 1.394 + _deopt_state = not_deoptimized; 1.395 + } 1.396 +} 1.397 + 1.398 + 1.399 +static bool sp_is_valid(intptr_t* old_sp, intptr_t* young_sp, intptr_t* sp) { 1.400 + return (((intptr_t)sp & (2*wordSize-1)) == 0 && 1.401 + sp <= old_sp && 1.402 + sp >= young_sp); 1.403 +} 1.404 + 1.405 + 1.406 +/* 1.407 + Find the (biased) sp that is just younger than old_sp starting at sp. 1.408 + If not found return NULL. Register windows are assumed to be flushed. 1.409 +*/ 1.410 +intptr_t* frame::next_younger_sp_or_null(intptr_t* old_sp, intptr_t* sp) { 1.411 + 1.412 + intptr_t* previous_sp = NULL; 1.413 + intptr_t* orig_sp = sp; 1.414 + 1.415 + int max_frames = (old_sp - sp) / 16; // Minimum frame size is 16 1.416 + int max_frame2 = max_frames; 1.417 + while(sp != old_sp && sp_is_valid(old_sp, orig_sp, sp)) { 1.418 + if (max_frames-- <= 0) 1.419 + // too many frames have gone by; invalid parameters given to this function 1.420 + break; 1.421 + previous_sp = sp; 1.422 + sp = (intptr_t*)sp[FP->sp_offset_in_saved_window()]; 1.423 + sp = (intptr_t*)((intptr_t)sp + STACK_BIAS); 1.424 + } 1.425 + 1.426 + return (sp == old_sp ? previous_sp : NULL); 1.427 +} 1.428 + 1.429 +/* 1.430 + Determine if "sp" is a valid stack pointer. "sp" is assumed to be younger than 1.431 + "valid_sp". So if "sp" is valid itself then it should be possible to walk frames 1.432 + from "sp" to "valid_sp". The assumption is that the registers windows for the 1.433 + thread stack in question are flushed. 1.434 +*/ 1.435 +bool frame::is_valid_stack_pointer(intptr_t* valid_sp, intptr_t* sp) { 1.436 + return next_younger_sp_or_null(valid_sp, sp) != NULL; 1.437 +} 1.438 + 1.439 + 1.440 +bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) { 1.441 + assert(is_interpreted_frame(), "must be interpreter frame"); 1.442 + return this->fp() == fp; 1.443 +} 1.444 + 1.445 + 1.446 +void frame::pd_gc_epilog() { 1.447 + if (is_interpreted_frame()) { 1.448 + // set constant pool cache entry for interpreter 1.449 + methodOop m = interpreter_frame_method(); 1.450 + 1.451 + *interpreter_frame_cpoolcache_addr() = m->constants()->cache(); 1.452 + } 1.453 +} 1.454 + 1.455 + 1.456 +bool frame::is_interpreted_frame_valid() const { 1.457 +#ifdef CC_INTERP 1.458 + // Is there anything to do? 1.459 +#else 1.460 + assert(is_interpreted_frame(), "Not an interpreted frame"); 1.461 + // These are reasonable sanity checks 1.462 + if (fp() == 0 || (intptr_t(fp()) & (2*wordSize-1)) != 0) { 1.463 + return false; 1.464 + } 1.465 + if (sp() == 0 || (intptr_t(sp()) & (2*wordSize-1)) != 0) { 1.466 + return false; 1.467 + } 1.468 + const intptr_t interpreter_frame_initial_sp_offset = interpreter_frame_vm_local_words; 1.469 + if (fp() + interpreter_frame_initial_sp_offset < sp()) { 1.470 + return false; 1.471 + } 1.472 + // These are hacks to keep us out of trouble. 1.473 + // The problem with these is that they mask other problems 1.474 + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above 1.475 + return false; 1.476 + } 1.477 + if (fp() - sp() > 4096) { // stack frames shouldn't be large. 1.478 + return false; 1.479 + } 1.480 +#endif /* CC_INTERP */ 1.481 + return true; 1.482 +} 1.483 + 1.484 + 1.485 +// Windows have been flushed on entry (but not marked). Capture the pc that 1.486 +// is the return address to the frame that contains "sp" as its stack pointer. 1.487 +// This pc resides in the called of the frame corresponding to "sp". 1.488 +// As a side effect we mark this JavaFrameAnchor as having flushed the windows. 1.489 +// This side effect lets us mark stacked JavaFrameAnchors (stacked in the 1.490 +// call_helper) as flushed when we have flushed the windows for the most 1.491 +// recent (i.e. current) JavaFrameAnchor. This saves useless flushing calls 1.492 +// and lets us find the pc just once rather than multiple times as it did 1.493 +// in the bad old _post_Java_state days. 1.494 +// 1.495 +void JavaFrameAnchor::capture_last_Java_pc(intptr_t* sp) { 1.496 + if (last_Java_sp() != NULL && last_Java_pc() == NULL) { 1.497 + // try and find the sp just younger than _last_Java_sp 1.498 + intptr_t* _post_Java_sp = frame::next_younger_sp_or_null(last_Java_sp(), sp); 1.499 + // Really this should never fail otherwise VM call must have non-standard 1.500 + // frame linkage (bad) or stack is not properly flushed (worse). 1.501 + guarantee(_post_Java_sp != NULL, "bad stack!"); 1.502 + _last_Java_pc = (address) _post_Java_sp[ I7->sp_offset_in_saved_window()] + frame::pc_return_offset; 1.503 + 1.504 + } 1.505 + set_window_flushed(); 1.506 +} 1.507 + 1.508 +void JavaFrameAnchor::make_walkable(JavaThread* thread) { 1.509 + if (walkable()) return; 1.510 + // Eventually make an assert 1.511 + guarantee(Thread::current() == (Thread*)thread, "only current thread can flush its registers"); 1.512 + // We always flush in case the profiler wants it but we won't mark 1.513 + // the windows as flushed unless we have a last_Java_frame 1.514 + intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); 1.515 + if (last_Java_sp() != NULL ) { 1.516 + capture_last_Java_pc(sp); 1.517 + } 1.518 +} 1.519 + 1.520 +intptr_t* frame::entry_frame_argument_at(int offset) const { 1.521 + // convert offset to index to deal with tsi 1.522 + int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize); 1.523 + 1.524 + intptr_t* LSP = (intptr_t*) sp()[Lentry_args->sp_offset_in_saved_window()]; 1.525 + return &LSP[index+1]; 1.526 +} 1.527 + 1.528 + 1.529 +BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { 1.530 + assert(is_interpreted_frame(), "interpreted frame expected"); 1.531 + methodOop method = interpreter_frame_method(); 1.532 + BasicType type = method->result_type(); 1.533 + 1.534 + if (method->is_native()) { 1.535 + // Prior to notifying the runtime of the method_exit the possible result 1.536 + // value is saved to l_scratch and d_scratch. 1.537 + 1.538 +#ifdef CC_INTERP 1.539 + interpreterState istate = get_interpreterState(); 1.540 + intptr_t* l_scratch = (intptr_t*) &istate->_native_lresult; 1.541 + intptr_t* d_scratch = (intptr_t*) &istate->_native_fresult; 1.542 +#else /* CC_INTERP */ 1.543 + intptr_t* l_scratch = fp() + interpreter_frame_l_scratch_fp_offset; 1.544 + intptr_t* d_scratch = fp() + interpreter_frame_d_scratch_fp_offset; 1.545 +#endif /* CC_INTERP */ 1.546 + 1.547 + address l_addr = (address)l_scratch; 1.548 +#ifdef _LP64 1.549 + // On 64-bit the result for 1/8/16/32-bit result types is in the other 1.550 + // word half 1.551 + l_addr += wordSize/2; 1.552 +#endif 1.553 + 1.554 + switch (type) { 1.555 + case T_OBJECT: 1.556 + case T_ARRAY: { 1.557 +#ifdef CC_INTERP 1.558 + *oop_result = istate->_oop_temp; 1.559 +#else 1.560 + oop obj = (oop) at(interpreter_frame_oop_temp_offset); 1.561 + assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); 1.562 + *oop_result = obj; 1.563 +#endif // CC_INTERP 1.564 + break; 1.565 + } 1.566 + 1.567 + case T_BOOLEAN : { jint* p = (jint*)l_addr; value_result->z = (jboolean)((*p) & 0x1); break; } 1.568 + case T_BYTE : { jint* p = (jint*)l_addr; value_result->b = (jbyte)((*p) & 0xff); break; } 1.569 + case T_CHAR : { jint* p = (jint*)l_addr; value_result->c = (jchar)((*p) & 0xffff); break; } 1.570 + case T_SHORT : { jint* p = (jint*)l_addr; value_result->s = (jshort)((*p) & 0xffff); break; } 1.571 + case T_INT : value_result->i = *(jint*)l_addr; break; 1.572 + case T_LONG : value_result->j = *(jlong*)l_scratch; break; 1.573 + case T_FLOAT : value_result->f = *(jfloat*)d_scratch; break; 1.574 + case T_DOUBLE : value_result->d = *(jdouble*)d_scratch; break; 1.575 + case T_VOID : /* Nothing to do */ break; 1.576 + default : ShouldNotReachHere(); 1.577 + } 1.578 + } else { 1.579 + intptr_t* tos_addr = interpreter_frame_tos_address(); 1.580 + 1.581 + switch(type) { 1.582 + case T_OBJECT: 1.583 + case T_ARRAY: { 1.584 + oop obj = (oop)*tos_addr; 1.585 + assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); 1.586 + *oop_result = obj; 1.587 + break; 1.588 + } 1.589 + case T_BOOLEAN : { jint* p = (jint*)tos_addr; value_result->z = (jboolean)((*p) & 0x1); break; } 1.590 + case T_BYTE : { jint* p = (jint*)tos_addr; value_result->b = (jbyte)((*p) & 0xff); break; } 1.591 + case T_CHAR : { jint* p = (jint*)tos_addr; value_result->c = (jchar)((*p) & 0xffff); break; } 1.592 + case T_SHORT : { jint* p = (jint*)tos_addr; value_result->s = (jshort)((*p) & 0xffff); break; } 1.593 + case T_INT : value_result->i = *(jint*)tos_addr; break; 1.594 + case T_LONG : value_result->j = *(jlong*)tos_addr; break; 1.595 + case T_FLOAT : value_result->f = *(jfloat*)tos_addr; break; 1.596 + case T_DOUBLE : value_result->d = *(jdouble*)tos_addr; break; 1.597 + case T_VOID : /* Nothing to do */ break; 1.598 + default : ShouldNotReachHere(); 1.599 + } 1.600 + }; 1.601 + 1.602 + return type; 1.603 +} 1.604 + 1.605 +// Lesp pointer is one word lower than the top item on the stack. 1.606 +intptr_t* frame::interpreter_frame_tos_at(jint offset) const { 1.607 + int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize) - 1; 1.608 + return &interpreter_frame_tos_address()[index]; 1.609 +}