Exemplo n.º 1
0
void Thread::grow_execution_stack(int new_stack_size JVM_TRAPS) {
  ExecutionStack::Raw new_stack = Universe::new_execution_stack(new_stack_size
                                                                JVM_CHECK);
  ExecutionStack::Raw old_stack = execution_stack();
  jint           old_stack_size = old_stack().length();
  GUARANTEE(new_stack_size > old_stack_size, "sanity check");

  GCDisabler dont_gc_for_rest_of_this_method;

  address   old_stack_ptr   = (address)stack_pointer();
  jint      stack_used_size;
  jint      delta;
  if (JavaStackDirection < 0) {
    address old_stack_end = (address)old_stack().field_base(old_stack_size);
    address new_stack_end = (address)new_stack().field_base(new_stack_size);
#ifdef UNDER_CE
    stack_used_size = (address)((int)old_stack_end | _system_address)
                                    - old_stack_ptr;
#else
    stack_used_size = old_stack_end - old_stack_ptr;
#endif
    delta = new_stack_end - old_stack_end;
  } else {
    const int offset          = ExecutionStackDesc::header_size();
    address   old_stack_start = (address)old_stack().field_base(offset);
    address   new_stack_start = (address)new_stack().field_base(offset);
#ifdef UNDER_CE
    stack_used_size = old_stack_ptr -
        (address)((int)old_stack_start | _system_address);
#else
    stack_used_size = old_stack_ptr - old_stack_start;
#endif
    delta = new_stack_start - old_stack_start;
  }
  address   new_stack_ptr   = old_stack_ptr + delta;

  ((ExecutionStackDesc*)(old_stack.obj()))->relocate_internal_pointers(delta,
                                                                       this,
                                                                       true);
  GUARANTEE((address)stack_pointer() == new_stack_ptr, "sanity");

  if (JavaStackDirection < 0) {
    jvm_memcpy(new_stack_ptr, old_stack_ptr  , stack_used_size);
  } else {
    jvm_memcpy(new_stack_ptr - stack_used_size,
               old_stack_ptr - stack_used_size,
               stack_used_size + 4);
  }
  old_stack().clear_thread();

  set_execution_stack(&new_stack);
  new_stack().set_thread(this);

  set_stack_limit();
}
Exemplo n.º 2
0
unsigned long return_address(unsigned level)
{
	struct return_addr_data r = {
		.skip = level + 1,
	};
	walk_stackframe(stack_pointer(NULL), return_address_cb, &r);
	return r.addr;
}
EXPORT_SYMBOL(return_address);
Exemplo n.º 3
0
VMReg FrameMap::regname(LIR_Opr opr) const {
  if (opr->is_single_cpu()) {
    assert(!opr->is_virtual(), "should not see virtual registers here");
    return opr->as_register()->as_VMReg();
  } else if (opr->is_single_stack()) {
    return sp_offset2vmreg(sp_offset_for_slot(opr->single_stack_ix()));
  } else if (opr->is_address()) {
    LIR_Address* addr = opr->as_address_ptr();
    assert(addr->base() == stack_pointer(), "sp based addressing only");
    return sp_offset2vmreg(in_ByteSize(addr->index()->as_jint()));
  }
  ShouldNotReachHere();
  return VMRegImpl::Bad();
}
Exemplo n.º 4
0
void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
{
	struct stack_trace_data trace_data = {
		.trace = trace,
		.skip = trace->skip,
	};
	walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data);
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);

void save_stack_trace(struct stack_trace *trace)
{
	save_stack_trace_tsk(current, trace);
}
bool VirtualStackFrame::flush_quick() {
  if (ENABLE_JAVA_STACK_TAGS) {
    return false;
  }

  int current_stack_ptr = stack_pointer();
  int virtual_stack_ptr = virtual_stack_pointer();

  if (current_stack_ptr >= virtual_stack_ptr) {
    // Not possible to use writeback addressing modes
    return false;
  }

  // This happens quite often, especially if we are making a series of
  // calls like:
  //
  //    iload_0
  //    invokestatic  void foo(int);
  //    iload_0
  //    iload_1
  //    invokestatic  void bar(int, int);
  //
  // During the second call, the top two VSF locations are in register
  // and must be flushed. The other VSF locations are already flushed
  // because of the first call. So (assuming we have downward-growing
  // full stack) we can use two pre-decrement STRs to store the top two
  // locations.
  //
  // IMPL_NOTE: consider using STM to save code footprint. However, doing
  // so might be slower than using individual STRs on Xscale

  {
    AllocationDisabler allocation_not_allowed;
    RawLocation *raw_location = raw_location_at(0);
    RawLocation *end = raw_location_end(raw_location);
    int index = 0;

    while (raw_location < end) {
      BasicType type = raw_location->type();
      if (is_two_word(type)) {
        return false; // uncommon. Just bail out.
      }
#if ENABLE_ARM_VFP
      if (type == T_FLOAT) {
        return false; // TEMP: fsts supports pre-indexing as well
      }
#endif
      bool changed = raw_location->is_changed();
      if (index <= current_stack_ptr) {
        if (changed) {
          return false;
        }
      } else {
        if (!changed) {
          return false;
        }
        if (!raw_location->in_register()) {
          return false;
        }
      }

      index ++;
      raw_location++;
    }
  }

  // Is this necessary?
  code_generator()->write_literals_if_desperate();

  {
    AllocationDisabler allocation_not_allowed;
    const Assembler::Register jsp = Assembler::jsp;
    const int offset = BytesPerStackElement * JavaStackDirection;

    RawLocation *raw_location = raw_location_at(0);
    RawLocation *end = raw_location_end(raw_location);
    int index = 0;

    while (raw_location < end) {
      if (index <= current_stack_ptr) {
        raw_location->mark_as_flushed();
      } else {
        Assembler::Register reg = raw_location->get_register();
        Assembler::Address2 addr;

        addr = Assembler::imm_index(jsp, offset, Assembler::pre_indexed);

        code_generator()->str(reg, addr);
        raw_location->mark_as_flushed();
      }
      index ++;
      raw_location++;
    }
  }

  set_real_stack_pointer(virtual_stack_ptr);
  return true;
}