src/cpu/sparc/vm/frame_sparc.cpp

changeset 435
a61af66fc99e
child 542
93b6525e3b82
     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 +}

mercurial