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 }