00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_objArray_prims.cpp.incl"
00026 
00027 TRACE_FUNC(TraceObjArrayPrims, "objArray")
00028 
00029 int objArrayPrimitives::number_of_calls;
00030 
00031 #define ASSERT_RECEIVER assert(receiver->is_objArray(), "receiver must be object array")
00032 
00033 PRIM_DECL_2(objArrayPrimitives::allocateSize, oop receiver, oop argument) {
00034   PROLOGUE_2("allocateSize", receiver, argument);
00035   assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_objArray(),
00036          "receiver must object array class");
00037   if (!argument->is_smi())
00038     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00039 
00040   if (smiOop(argument)->value() < 0)
00041     return markSymbol(vmSymbols::negative_size());
00042 
00043   klassOop k        = klassOop(receiver);
00044   int      ni_size  = k->klass_part()->non_indexable_size();
00045   int      obj_size = ni_size + 1 + smiOop(argument)->value();
00046   
00047   objArrayOop obj = as_objArrayOop(Universe::allocate(obj_size, (memOop*)&k));
00048   
00049   memOop(obj)->initialize_header(k->klass_part()->has_untagged_contents(), k);
00050   
00051   memOop(obj)->initialize_body(memOopDesc::header_size(), ni_size);
00052   
00053   oop* base = (oop*) obj->addr();
00054   base[ni_size] = argument;
00055   memOop(obj)->initialize_body(ni_size+1, obj_size);
00056   return obj;
00057 }
00058 
00059 PRIM_DECL_1(objArrayPrimitives::size, oop receiver) {
00060   PROLOGUE_1("size", receiver);
00061   ASSERT_RECEIVER;
00062   
00063   return as_smiOop(objArrayOop(receiver)->length());
00064 }
00065 
00066 PRIM_DECL_2(objArrayPrimitives::at, oop receiver, oop index) {
00067   PROLOGUE_2("at", receiver, index);
00068   ASSERT_RECEIVER;
00069 
00070   
00071   if (!index->is_smi())
00072     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00073 
00074   
00075   if (!objArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00076      return markSymbol(vmSymbols::out_of_bounds());
00077 
00078   
00079   return objArrayOop(receiver)->obj_at(smiOop(index)->value());
00080 }
00081 
00082 PRIM_DECL_3(objArrayPrimitives::atPut, oop receiver, oop index, oop value) {
00083   PROLOGUE_3("atPut", receiver, index, value);
00084   ASSERT_RECEIVER;
00085 
00086   
00087   if (!index->is_smi())
00088     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00089 
00090   
00091   if (!objArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00092     return markSymbol(vmSymbols::out_of_bounds());
00093 
00094   
00095   objArrayOop(receiver)->obj_at_put(smiOop(index)->value(), value);
00096   return receiver;
00097 }
00098 
00099 
00100 PRIM_DECL_2(objArrayPrimitives::at_all_put, oop receiver, oop obj) {
00101   PROLOGUE_2("at_all_put", receiver, obj);
00102   ASSERT_RECEIVER;
00103 
00104   int  length = objArrayOop(receiver)->length();
00105   if (obj->is_new() && receiver->is_old()) {
00106     
00107     for (int index = 1; index <= length; index++) {
00108       objArrayOop(receiver)->obj_at_put(index, obj); 
00109     }
00110   } else {
00111     
00112     set_oops(objArrayOop(receiver)->objs(1), length, obj);
00113   }
00114   return receiver;
00115 }
00116 
00117 PRIM_DECL_5(objArrayPrimitives::replace_from_to, oop receiver, oop from, oop to, oop source, oop start) {
00118   PROLOGUE_5("replace_from_to", receiver, from, to, source, start);
00119   ASSERT_RECEIVER;
00120 
00121   
00122   if (!from->is_smi())
00123     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00124 
00125   
00126   if (!to->is_smi())
00127     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00128 
00129   
00130   if (!source->is_objArray())
00131     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00132 
00133   
00134   if (!start->is_smi())
00135     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00136 
00137   
00138   if (smiOop(from) <= 0)
00139     return markSymbol(vmSymbols::out_of_bounds());
00140 
00141   
00142   if (smiOop(to)->value() > objArrayOop(receiver)->length())
00143     return markSymbol(vmSymbols::out_of_bounds());
00144 
00145   
00146   if (smiOop(from)->value() > smiOop(to)->value())
00147     return markSymbol(vmSymbols::out_of_bounds());
00148 
00149   
00150   if (smiOop(start)->value() + (smiOop(to)->value() - smiOop(from)->value() + 1) > objArrayOop(source)->length())
00151     return markSymbol(vmSymbols::out_of_bounds());
00152 
00153   
00154   objArrayOop(receiver)->replace_from_to(smiOop(from)->value(), smiOop(to)->value(), objArrayOop(source), smiOop(start)->value());
00155 
00156   return receiver;
00157 }
00158 
00159 PRIM_DECL_4(objArrayPrimitives::copy_size, oop receiver, oop from, oop start, oop size) {
00160   PROLOGUE_4("copy_size", receiver, from, start, size);
00161   ASSERT_RECEIVER;
00162 
00163   
00164   if (!from->is_smi())
00165     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00166 
00167   
00168   if (!start->is_smi())
00169     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00170 
00171   
00172   if (!size->is_smi())
00173     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00174 
00175   
00176   if (smiOop(from) <= 0)
00177     return markSymbol(vmSymbols::out_of_bounds());
00178 
00179   
00180   if (smiOop(start) <= 0)
00181     return markSymbol(vmSymbols::out_of_bounds());
00182   
00183   
00184   if (smiOop(size)->value() < 0)
00185     return markSymbol(vmSymbols::negative_size());
00186 
00187   HandleMark hm;
00188   Handle saved_receiver(receiver); 
00189 
00190   
00191   klassOop k        = receiver->klass();
00192   int      ni_size  = k->klass_part()->non_indexable_size();
00193   int      obj_size = ni_size + 1 + smiOop(size)->value();
00194   
00195   objArrayOop obj = as_objArrayOop(Universe::allocate(obj_size, (memOop*)&k));
00196 
00197   objArrayOop src = saved_receiver.as_objArray();
00198 
00199   
00200   memOop(obj)->initialize_header(k->klass_part()->has_untagged_contents(), k);
00201   
00202   for (int index = memOopDesc::header_size(); index < ni_size; index++ ) {
00203      obj->raw_at_put(index, src->raw_at(index));
00204   }
00205   
00206   obj->set_length(smiOop(size)->value());
00207   
00208   obj->replace_and_fill(smiOop(from)->value(), smiOop(start)->value(), src);
00209 
00210   return obj;
00211 }