예제 #1
0
void ObjArrayKlass::oop_oop_iterate_elements_specialized(objArrayOop a, OopClosureType* closure) {
  T* p         = (T*)a->base();
  T* const end = p + a->length();

  for (;p < end; p++) {
    Devirtualizer<nv>::do_oop(closure, p);
  }
}
예제 #2
0
 static objArrayOop extend(objArrayOop old_pic) {
   int old_size = old_pic->length()/2;
   if (old_size >= size_of_largest_interpreterPIC) return NULL;
   objArrayOop result = allocate(old_size + 1);
   for (int index = 1; index <= old_size*2; index++) {
     result->obj_at_put(index, old_pic->obj_at(index));
   }
   return result;
 }
예제 #3
0
// this function computes the vtable size (including the size needed for miranda
// methods) and the number of miranda methods in this class
// Note on Miranda methods: Let's say there is a class C that implements
// interface I.  Let's say there is a method m in I that neither C nor any
// of its super classes implement (i.e there is no method of any access, with
// the same name and signature as m), then m is a Miranda method which is
// entered as a public abstract method in C's vtable.  From then on it should
// treated as any other public method in C for method over-ride purposes.
void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
                                                       int &num_miranda_methods,
                                                       klassOop super,
                                                       objArrayOop methods,
                                                       AccessFlags class_flags,
                                                       Handle classloader,
                                                       Symbol* classname,
                                                       objArrayOop local_interfaces,
                                                       TRAPS
                                                       ) {

  No_Safepoint_Verifier nsv;

  // set up default result values
  vtable_length = 0;
  num_miranda_methods = 0;

  // start off with super's vtable length
  instanceKlass* sk = (instanceKlass*)super->klass_part();
  vtable_length = super == NULL ? 0 : sk->vtable_length();

  // go thru each method in the methods table to see if it needs a new entry
  int len = methods->length();
  for (int i = 0; i < len; i++) {
    assert(methods->obj_at(i)->is_method(), "must be a methodOop");
    methodHandle mh(THREAD, methodOop(methods->obj_at(i)));

    if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) {
      vtable_length += vtableEntry::size(); // we need a new entry
    }
  }

  // compute the number of mirandas methods that must be added to the end
  num_miranda_methods = get_num_mirandas(super, methods, local_interfaces);
  vtable_length += (num_miranda_methods * vtableEntry::size());

  if (Universe::is_bootstrapping() && vtable_length == 0) {
    // array classes don't have their superclass set correctly during
    // bootstrapping
    vtable_length = Universe::base_vtable_size();
  }

  if (super == NULL && !Universe::is_bootstrapping() &&
      vtable_length != Universe::base_vtable_size()) {
    // Someone is attempting to redefine java.lang.Object incorrectly.  The
    // only way this should happen is from
    // SystemDictionary::resolve_from_stream(), which will detect this later
    // and throw a security exception.  So don't assert here to let
    // the exception occur.
    vtable_length = Universe::base_vtable_size();
  }
  assert(super != NULL || vtable_length == Universe::base_vtable_size(),
         "bad vtable size for class Object");
  assert(vtable_length % vtableEntry::size() == 0, "bad vtable length");
  assert(vtable_length >= Universe::base_vtable_size(), "vtable too small");
}
예제 #4
0
 void flush_method_JNIid_cache() {
   for (int i = 0; i < _old_methods->length(); i++) {
     methodOop mop = (methodOop)_old_methods->obj_at(i);
     JNIid *mid = mop->jni_id();
     if (mid != NULL) {
       // don't need to call JNIid::lock() since we are at a safepoint
       mid->set_resolved_method((methodOop)NULL, (klassOop)NULL);
     }
   }
 }
예제 #5
0
void ObjArrayKlass::oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end) {
  if (Devirtualizer<nv>::do_metadata(closure)) {
    Devirtualizer<nv>::do_klass(closure, a->klass());
  }

  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr<T>(start);
  T* high = (T*)a->base() + end;

  oop_oop_iterate_elements_specialized_bounded<nv, T>(a, closure, low, high);
}
예제 #6
0
 void check_methods_and_mark_as_old() {
   for (int i = 0; i < _old_methods->length(); i++) {
     methodOop old_method = (methodOop) _old_methods->obj_at(i);
     old_method->set_old_version();
     if (jvmdi::enabled()) {
         methodOop new_method = (methodOop) _new_methods->obj_at(i);
         if (!MethodComparator::methods_EMCP(old_method, new_method)) {
             // Mark non-EMCP methods as such
             old_method->set_non_emcp_with_new_version();
         }
     }
   }
 }
예제 #7
0
void constantPoolCacheOopDesc::adjust_method_entries(objArrayOop old_methods,
						     objArrayOop new_methods) {
  for (int i = 0; i < old_methods->length(); i++) {
    methodOop old_method = (methodOop) old_methods->obj_at(i);
    if (! old_method->is_old_version())
      continue;
    for (int j = 0; j < length(); j++) {
      if (entry_at(j)->is_method_entry()) {
	entry_at(j)->adjust_method_entry(old_method, (methodOop) new_methods->obj_at(i));
      }
    }
  }
}
예제 #8
0
extern "C" oop* setup_deoptimization_and_return_new_sp(oop* old_sp, int* old_fp, objArrayOop frame_array, int* current_frame) {
  ResourceMark rm;

  // Save all parameters for later use (check unpack_frame_array)
  ::old_sp      = old_sp;
  ::old_fp      = old_fp;
  ::frame_array = frame_array;
  ::cur_fp      = current_frame;

  smiOop number_of_vframes = smiOop(frame_array->obj_at(StackChunkBuilder::number_of_vframes_index));
  smiOop number_of_locals  = smiOop(frame_array->obj_at(StackChunkBuilder::number_of_locals_index));

  assert(number_of_vframes->is_smi(), "must be smi");
  assert(number_of_locals->is_smi(), "must be smi");

  new_sp = old_sp - frame::interpreter_stack_size(number_of_vframes->value(),
	                                          number_of_locals->value());
  return new_sp;
}
inline void oop_pc_follow_contents_specialized(objArrayOop obj, int index, ParCompactionManager* cm) {
  const size_t len = size_t(obj->length());
  const size_t beg_index = size_t(index);
  assert(beg_index < len || len == 0, "index too large");

  const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
  const size_t end_index = beg_index + stride;
  T* const base = (T*)obj->base();
  T* const beg = base + beg_index;
  T* const end = base + end_index;

  // Push the non-NULL elements of the next stride on the marking stack.
  for (T* e = beg; e < end; e++) {
    cm->mark_and_push<T>(e);
  }

  if (end_index < len) {
    cm->push_objarray(obj, end_index); // Push the continuation.
  }
}
예제 #10
0
void ObjArrayKlass::oop_oop_iterate_elements_specialized_bounded(
    objArrayOop a, OopClosureType* closure, void* low, void* high) {

  T* const l = (T*)low;
  T* const h = (T*)high;

  T* p   = (T*)a->base();
  T* end = p + a->length();

  if (p < l) {
    p = l;
  }
  if (end > h) {
    end = h;
  }

  for (;p < end; ++p) {
    Devirtualizer<nv>::do_oop(closure, p);
  }
}
예제 #11
0
inline void trace_deoptimization_start() {
  if (TraceDeoptimization) {
    std->print("[Unpacking]");
    if (nlr_through_unpacking) {
      std->print(" NLR %s", (nlr_home == (int) cur_fp) ? "inside" : "outside");
    }
    std->cr();
    std->print(" - array ");
    frame_array->print_value();
    std->print_cr(" @ 0x%lx", old_fp);
  }
}
예제 #12
0
inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
  obj->oop_iterate(_cm_oop_closure, mr);
  return mr.word_size();
}
예제 #13
0
// Called from assembler in unpack_unoptimized_frames.
// Based on the statics (old_sp, old_fp, and frame_array) this function unpacks
// the array into interpreter frames.
// Returning from this function should activate the most recent deoptimized frame.
extern "C" void unpack_frame_array() {
  BlockScavenge bs;
  ResourceMark rm;

  int* pc_addr = (int*) new_sp - 1;
  assert(*pc_addr = -1, "just checking");

  if (TraceDeoptimization) {
    std->print("[Unpacking]");
    if (nlr_through_unpacking) {
      std->print(" NLR %s", (nlr_home == (int) cur_fp) ? "inside" : "outside");
    }
    std->cr();
    std->print(" - array ");
    frame_array->print_value();
    std->print_cr(" @ 0x%lx", old_fp);
  }

  bool must_find_nlr_target = nlr_through_unpacking && nlr_home == (int) cur_fp;
  bool nlr_target_found     = false; // For verification

  // link for the current frame
  int* link_addr = (int*) new_sp - 2;

  oop* current_sp = new_sp;
  int  pos        = 3;
  int  length     = frame_array->length();
  bool first = true;
  frame current;
  // unpack one frame at at time from most recent to least recent
  do {
    oop receiver     = frame_array->obj_at(pos++);
    methodOop method = methodOop(frame_array->obj_at(pos++));
    assert(method->is_method(), "expecting method");

    smiOop bci_obj = smiOop(frame_array->obj_at(pos++));
    assert(bci_obj->is_smi(), "expecting smi");
    int bci        = bci_obj->value();

    smiOop locals_obj = smiOop(frame_array->obj_at(pos++));
    assert(locals_obj->is_smi(), "expecting smi");
    int locals   = locals_obj->value();

    current = frame(current_sp, (int*) current_sp + locals + 2);

    // fill in the locals
    for (int index = 0; index < locals; index++) {
      current.set_temp(index, frame_array->obj_at(pos++));
    }

    CodeIterator c(method, bci);

    char* current_pc;

    if (first) {
      // first vframe in the array
      if (nlr_through_unpacking) {
        // NLR is comming through unpacked vframes
        current_pc = c.interpreter_return_point();
        // current_pc points to a normal return point in the interpreter.
	// To find the nlr return point we first compute the nlr offset.
        current_pc = ic_info_at(current_pc)->NLR_target();
        current.set_hp(c.next_hp());
      } else if (redo_the_send) {
        // Deoptimizing uncommon trap
        current_pc = (char*) redo_bytecode_after_deoptimization;
        current.set_hp(c.next_hp());
	redo_send_offset = c.next_hp() - c.hp();
        redo_the_send = false;
      } else {
        // Normal case
        current_pc = c.interpreter_return_point(true);
        current.set_hp(c.next_hp());
 
        if (c.is_message_send()) {
	  number_of_arguments_through_unpacking = c.ic()->nof_arguments();	  
        } else if (c.is_primitive_call()) {
          number_of_arguments_through_unpacking = c.prim_cache()->number_of_parameters();
	} else if (c.is_dll_call()) {
	  // The callee should not pop the argument since a DLL call is like a c function call.
	  // The continuation code for the DLL call will pop the arguments!
          number_of_arguments_through_unpacking = 0;
	}
      }
    } else {
      current_pc = c.interpreter_return_point();
      current.set_hp(c.next_hp());
    }
    current.set_receiver(receiver);

    current.patch_pc(current_pc);
    current.patch_fp(current.fp());
    
    // Revive the contexts
    if (!method->is_blockMethod() && method->activation_has_context()) {
      contextOop con = contextOop(current.temp(0));
      assert(con->is_context(), "must be context");
      oop frame_oop = oop(current.fp());
      con->set_parent(frame_oop);

      if (nlr_through_unpacking && nlr_home == (int) cur_fp) {
        if (nlr_home_context == con) {
	  // This frame is the target of the NLR
	  // set nlr_home to frame pointer of current frame
	  nlr_home = (int) current.fp();
	  // compute number of arguments to pop
          nlr_home_id = ~method->number_of_arguments();
          nlr_target_found = true;
	  // std->print("target frame for NLR (%d, 0x%lx):",method->number_of_arguments(), nlr_home_id);
        }
      }
    }

    if (TraceDeoptimization) {
      frame v(current_sp, current.fp(), current_pc);
      v.print_for_deoptimization(std);
    }

    first = false;
    // Next pc
    current_sp += frame::interpreter_frame_size(locals);

  } while (pos <= length);

  if (must_find_nlr_target && !nlr_target_found) {
    fatal("Target for NLR not found when unpacking frame");
  }

  assert (current_sp == old_sp, "We have not reached the end");
  current.set_link(old_fp);
}
예제 #14
0
// Called from assembler in unpack_unoptimized_frames.
// Based on the statics (old_sp, old_fp, and frame_array) this function unpacks
// the array into interpreter frames.
// Returning from this function should activate the most recent deoptimized frame.
extern "C" void unpack_frame_array() {
  BlockScavenge bs;
  ResourceMark rm;

  int* pc_addr = (int*) new_sp - 1;
  assert(*pc_addr = -1, "just checking");

  trace_deoptimization_start();

  bool must_find_nlr_target = nlr_through_unpacking && nlr_home == (int) cur_fp;
  bool nlr_target_found     = false; // For verification

  // link for the current frame
  int* link_addr = (int*) new_sp - 2;

  oop* current_sp = new_sp;
  int  pos        = 3;
  int  length     = frame_array->length();
  bool first = true;
  frame current;
  // unpack one frame at at time from most recent to least recent
  do {
    oop receiver     = frame_array->obj_at(pos++);
    methodOop method = methodOop(frame_array->obj_at(pos++));
    assert(method->is_method(), "expecting method");

    smiOop bci_obj = smiOop(frame_array->obj_at(pos++));
    assert(bci_obj->is_smi(), "expecting smi");
    int bci        = bci_obj->value();

    smiOop locals_obj = smiOop(frame_array->obj_at(pos++));
    assert(locals_obj->is_smi(), "expecting smi");
    int locals   = locals_obj->value();

    current = frame(current_sp, (int*) current_sp + locals + 2);

    // fill in the locals
    for (int index = 0; index < locals; index++) {
      current.set_temp(index, frame_array->obj_at(pos++));
    }

    CodeIterator c(method, bci);

    char* current_pc;

    if (first) {
      unpack_first_frame(current_pc, current, c);
    } else {
      current_pc = c.interpreter_return_point();
      current.set_hp(c.next_hp());
    }
    current.set_receiver(receiver);

    current.patch_pc(current_pc);
    current.patch_fp(current.fp());

    // Revive the contexts
    if (!method->is_blockMethod() && method->activation_has_context()) {
      contextOop con = contextOop(current.temp(0));
      assert(con->is_context(), "must be context");
      oop frame_oop = oop(current.fp());
      con->set_parent(frame_oop);

      if (nlr_through_unpacking && nlr_home == (int) cur_fp) {
        if (nlr_home_context == con) {
	  // This frame is the target of the NLR
	  // set nlr_home to frame pointer of current frame
	  nlr_home = (int) current.fp();
	  // compute number of arguments to pop
          nlr_home_id = ~method->number_of_arguments();
          nlr_target_found = true;
	  // std->print("target frame for NLR (%d, 0x%lx):",method->number_of_arguments(), nlr_home_id);
        }
      }
    }

    trace_deoptimization_frame(current, current_sp, current_pc);

    first = false;
    // Next pc
    current_sp += frame::interpreter_frame_size(locals);

  } while (pos <= length);

  if (must_find_nlr_target && !nlr_target_found) {
    fatal("Target for NLR not found when unpacking frame");
  }

  assert (current_sp == old_sp, "We have not reached the end");
  current.set_link(old_fp);
}
예제 #15
0
void ObjArrayKlass::oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end) {
  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr<T>(start);
  T* high = (T*)a->base() + end;

  oop_oop_iterate_elements_specialized_bounded<nv, T>(a, closure, low, high);
}
예제 #16
0
 static void deallocate(objArrayOop pic) {
   int entry = (pic->length()/2) - 1;
   oop first = free_list()->obj_at(entry);
   pic->obj_at_put(1, first);
   free_list()->obj_at_put(entry, pic);
 }
예제 #17
0
 static void set_first(objArrayOop pic, oop first, oop second) {
   pic->obj_at_put(1, first);
   pic->obj_at_put(2, second);
 }
예제 #18
0
 static void set_last(objArrayOop pic, oop first, oop second) {
   int size = pic->length();
   pic->obj_at_put(size--, second);
   pic->obj_at_put(size,   first);
 }
예제 #19
0
 static void set_second(objArrayOop pic, oop first, oop second) {
   pic->obj_at_put(3, first);
   pic->obj_at_put(4, second);
 }