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/_byteArray_prims.cpp.incl"
00026
00027 TRACE_FUNC(TraceByteArrayPrims, "byteArray")
00028
00029 int byteArrayPrimitives::number_of_calls;
00030
00031 #define ASSERT_RECEIVER assert(receiver->is_byteArray(), "receiver must be byte array")
00032
00033 PRIM_DECL_2(byteArrayPrimitives::allocateSize, oop receiver, oop argument) {
00034 PROLOGUE_2("allocateSize", receiver, argument)
00035 assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_byteArray(),
00036 "receiver must byte 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 + roundTo(smiOop(argument)->value(), oopSize) / oopSize;
00046
00047 byteArrayOop obj = as_byteArrayOop(Universe::allocate(obj_size, (memOop*)&k));
00048
00049 memOop(obj)->initialize_header(true, k);
00050
00051 memOop(obj)->initialize_body(memOopDesc::header_size(), ni_size);
00052
00053 oop* base = (oop*) obj->addr();
00054 oop* end = base + obj_size;
00055
00056 base[ni_size] = argument;
00057
00058
00059 base = &base[ni_size+1];
00060 while (base < end) *base++ = (oop) 0;
00061 return obj;
00062 }
00063
00064 PRIM_DECL_1(byteArrayPrimitives::size, oop receiver) {
00065 PROLOGUE_1("size", receiver);
00066 ASSERT_RECEIVER;
00067
00068 return as_smiOop(byteArrayOop(receiver)->length());
00069 }
00070
00071 PRIM_DECL_2(byteArrayPrimitives::at, oop receiver, oop index) {
00072 PROLOGUE_2("at", receiver, index);
00073 ASSERT_RECEIVER;
00074
00075
00076 if (!index->is_smi())
00077 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00078
00079
00080 if (!byteArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00081 return markSymbol(vmSymbols::out_of_bounds());
00082
00083
00084 return as_smiOop(byteArrayOop(receiver)->byte_at(smiOop(index)->value()));
00085 }
00086
00087 PRIM_DECL_3(byteArrayPrimitives::atPut, oop receiver, oop index, oop value) {
00088 PROLOGUE_3("atPut", receiver, index, value);
00089 ASSERT_RECEIVER;
00090
00091
00092 if (!index->is_smi())
00093 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00094
00095
00096 if (!value->is_smi())
00097 return markSymbol(vmSymbols::second_argument_has_wrong_type());
00098
00099
00100 if (!byteArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00101 return markSymbol(vmSymbols::out_of_bounds());
00102
00103
00104 unsigned int v = (unsigned int) smiOop(value)->value();
00105 if (v >= (1<<8))
00106 return markSymbol(vmSymbols::value_out_of_range());
00107
00108
00109 byteArrayOop(receiver)->byte_at_put(smiOop(index)->value(), v);
00110 return receiver;
00111 }
00112
00113 PRIM_DECL_2(byteArrayPrimitives::compare, oop receiver, oop argument) {
00114 PROLOGUE_2("comare", receiver, argument);
00115 ASSERT_RECEIVER;
00116
00117 if( receiver == argument)
00118 return as_smiOop(0);
00119
00120 if (argument->is_byteArray())
00121 return as_smiOop(byteArrayOop(receiver)->compare(byteArrayOop(argument)));
00122
00123 if (argument->is_doubleByteArray())
00124 return as_smiOop(byteArrayOop(receiver)->compare_doubleBytes(doubleByteArrayOop(argument)));
00125
00126 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00127 }
00128
00129 PRIM_DECL_1(byteArrayPrimitives::intern, oop receiver) {
00130 PROLOGUE_1("intern", receiver);
00131 ASSERT_RECEIVER;
00132
00133 return Universe::symbol_table->lookup(byteArrayOop(receiver)->chars(),
00134 byteArrayOop(receiver)->length());
00135 }
00136
00137 PRIM_DECL_2(byteArrayPrimitives::characterAt, oop receiver, oop index) {
00138 PROLOGUE_2("characterAt", receiver, index);
00139 ASSERT_RECEIVER;
00140
00141
00142 if (!index->is_smi())
00143 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00144
00145
00146 if (!byteArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00147 return markSymbol(vmSymbols::out_of_bounds());
00148
00149
00150 int byte = byteArrayOop(receiver)->byte_at(smiOop(index)->value());
00151
00152
00153 return Universe::asciiCharacters()->obj_at(byte+1);
00154 }
00155
00156 PRIM_DECL_2(byteArrayPrimitives::at_all_put, oop receiver, oop value) {
00157 PROLOGUE_2("at_all_put", receiver, value);
00158 ASSERT_RECEIVER;
00159
00160
00161 if (!value->is_smi())
00162 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00163
00164
00165 unsigned int v = (unsigned int) smiOop(value)->value();
00166 if (v >= (1<<8))
00167 return markSymbol(vmSymbols::value_out_of_range());
00168
00169 int length = byteArrayOop(receiver)->length();
00170 for (int index = 1; index <= length; index++) {
00171 byteArrayOop(receiver)->byte_at_put(index, v);
00172 }
00173 return receiver;
00174 }
00175
00176
00177
00178 oop simplified(byteArrayOop result) {
00179
00180 bool ok;
00181 oop smi_result = result->number().as_smi(ok);
00182 return ok ? smi_result : result;
00183 }
00184
00185 PRIM_DECL_2(byteArrayPrimitives::largeIntegerFromSmallInteger, oop receiver, oop number) {
00186 PROLOGUE_2("largeIntegerFromSmallInteger", receiver, number);
00187 assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_byteArray(), "just checking");
00188
00189
00190 if (!number->is_smi()) return markSymbol(vmSymbols::second_argument_has_wrong_type());
00191
00192 BlockScavenge bs;
00193 int i = smiOop(number)->value();
00194 byteArrayOop z;
00195
00196 z = byteArrayOop(klassOop(receiver)->klass_part()->allocateObjectSize(IntegerOps::int_to_Integer_result_size_in_bytes(i)));
00197 IntegerOps::int_to_Integer(i, z->number());
00198 return z;
00199 }
00200
00201 PRIM_DECL_2(byteArrayPrimitives::largeIntegerFromDouble, oop receiver, oop number) {
00202 PROLOGUE_2("largeIntegerFromDouble", receiver, number);
00203 assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_byteArray(), "just checking");
00204
00205 if (!number->is_double()) return markSymbol(vmSymbols::first_argument_has_wrong_type());
00206
00207 BlockScavenge bs;
00208 double x = doubleOop(number)->value();
00209 byteArrayOop z;
00210
00211 z = byteArrayOop(klassOop(receiver)->klass_part()->allocateObjectSize(IntegerOps::double_to_Integer_result_size_in_bytes(x)));
00212 IntegerOps::double_to_Integer(x, z->number());
00213 return z;
00214 }
00215
00216 PRIM_DECL_3(byteArrayPrimitives::largeIntegerFromString, oop receiver, oop argument, oop base) {
00217 PROLOGUE_3("largeIntegerFromString", receiver, argument, base);
00218 assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_byteArray(), "just checking");
00219
00220 if (!argument->is_byteArray()) return markSymbol(vmSymbols::first_argument_has_wrong_type ());
00221 if (!base->is_smi() ) return markSymbol(vmSymbols::second_argument_has_wrong_type());
00222
00223 BlockScavenge bs;
00224
00225 byteArrayOop x = byteArrayOop(argument);
00226 byteArrayOop z;
00227
00228 z = byteArrayOop(x->klass()->klass_part()->allocateObjectSize(IntegerOps::string_to_Integer_result_size_in_bytes(x->chars(), smiOop(base)->value())));
00229 IntegerOps::string_to_Integer(x->chars(), smiOop(base)->value(), z->number());
00230 return z;
00231 }
00232
00233 PRIM_DECL_2(byteArrayPrimitives::largeIntegerAdd, oop receiver, oop argument) {
00234 PROLOGUE_2("largeIntegerAdd", receiver, argument);
00235 ASSERT_RECEIVER;
00236
00237 if (!argument->is_byteArray())
00238 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00239
00240 BlockScavenge bs;
00241
00242 byteArrayOop x = byteArrayOop(receiver);
00243 byteArrayOop y = byteArrayOop(argument);
00244 byteArrayOop z;
00245
00246 if (!x->number().is_valid() || !y->number().is_valid()) return markSymbol(vmSymbols::argument_is_invalid());
00247
00248 z = byteArrayOop(x->klass()->klass_part()->allocateObjectSize(IntegerOps::add_result_size_in_bytes(x->number(), y->number())));
00249 x = byteArrayOop(receiver);
00250 y = byteArrayOop(argument);
00251 IntegerOps::add(x->number(), y->number(), z->number());
00252 return simplified(z);
00253 }
00254
00255 PRIM_DECL_2(byteArrayPrimitives::largeIntegerSubtract, oop receiver, oop argument) {
00256 PROLOGUE_2("largeIntegerSubtract", receiver, argument);
00257 ASSERT_RECEIVER;
00258
00259 if (!argument->is_byteArray())
00260 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00261
00262 BlockScavenge bs;
00263
00264 byteArrayOop x = byteArrayOop(receiver);
00265 byteArrayOop y = byteArrayOop(argument);
00266 byteArrayOop z;
00267
00268 if (!x->number().is_valid() || !y->number().is_valid()) return markSymbol(vmSymbols::argument_is_invalid());
00269
00270 z = byteArrayOop(x->klass()->klass_part()->allocateObjectSize(IntegerOps::sub_result_size_in_bytes(x->number(), y->number())));
00271 x = byteArrayOop(receiver);
00272 y = byteArrayOop(argument);
00273 IntegerOps::sub(x->number(), y->number(), z->number());
00274 return simplified(z);
00275 }
00276
00277 PRIM_DECL_2(byteArrayPrimitives::largeIntegerMultiply, oop receiver, oop argument) {
00278 PROLOGUE_2("largeIntegerMultiply", receiver, argument);
00279 ASSERT_RECEIVER;
00280
00281 if (!argument->is_byteArray())
00282 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00283
00284 BlockScavenge bs;
00285
00286 byteArrayOop x = byteArrayOop(receiver);
00287 byteArrayOop y = byteArrayOop(argument);
00288 byteArrayOop z;
00289
00290 if (!x->number().is_valid() || !y->number().is_valid()) return markSymbol(vmSymbols::argument_is_invalid());
00291
00292 z = byteArrayOop(x->klass()->klass_part()->allocateObjectSize(IntegerOps::mul_result_size_in_bytes(x->number(), y->number())));
00293 x = byteArrayOop(receiver);
00294 y = byteArrayOop(argument);
00295 IntegerOps::mul(x->number(), y->number(), z->number());
00296 return simplified(z);
00297 }
00298
00299 PRIM_DECL_2(byteArrayPrimitives::largeIntegerDiv, oop receiver, oop argument) {
00300 PROLOGUE_2("largeIntegerDiv", receiver, argument);
00301 ASSERT_RECEIVER;
00302
00303 if (!argument->is_byteArray())
00304 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00305
00306 BlockScavenge bs;
00307
00308 byteArrayOop x = byteArrayOop(receiver);
00309 byteArrayOop y = byteArrayOop(argument);
00310 byteArrayOop z;
00311
00312 if (!x->number().is_valid() || !y->number().is_valid()) return markSymbol(vmSymbols::argument_is_invalid());
00313 if (y->number().is_zero() ) return markSymbol(vmSymbols::division_by_zero ());
00314
00315 z = byteArrayOop(x->klass()->klass_part()->allocateObjectSize(IntegerOps::div_result_size_in_bytes(x->number(), y->number())));
00316 x = byteArrayOop(receiver);
00317 y = byteArrayOop(argument);
00318 IntegerOps::div(x->number(), y->number(), z->number());
00319 return simplified(z);
00320 }
00321
00322 PRIM_DECL_2(byteArrayPrimitives::largeIntegerMod, oop receiver, oop argument) {
00323 PROLOGUE_2("largeIntegerMod", receiver, argument);
00324 ASSERT_RECEIVER;
00325
00326 if (!argument->is_byteArray())
00327 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00328
00329 BlockScavenge bs;
00330
00331 byteArrayOop x = byteArrayOop(receiver);
00332 byteArrayOop y = byteArrayOop(argument);
00333 byteArrayOop z;
00334
00335 if (!x->number().is_valid() || !y->number().is_valid()) return markSymbol(vmSymbols::argument_is_invalid());
00336 if (y->number().is_zero() ) return markSymbol(vmSymbols::division_by_zero ());
00337
00338 z = byteArrayOop(x->klass()->klass_part()->allocateObjectSize(IntegerOps::mod_result_size_in_bytes(x->number(), y->number())));
00339 x = byteArrayOop(receiver);
00340 y = byteArrayOop(argument);
00341 IntegerOps::mod(x->number(), y->number(), z->number());
00342 return simplified(z);
00343 }
00344
00345 PRIM_DECL_2(byteArrayPrimitives::largeIntegerCompare, oop receiver, oop argument) {
00346 PROLOGUE_2("largeIntegerCompare", receiver, argument);
00347 ASSERT_RECEIVER;
00348
00349
00350 if (!argument->is_byteArray())
00351 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00352
00353 BlockScavenge bs;
00354
00355 byteArrayOop x = byteArrayOop(receiver);
00356 byteArrayOop y = byteArrayOop(argument);
00357
00358 if (!x->number().is_valid() || !y->number().is_valid()) return markSymbol(vmSymbols::argument_is_invalid());
00359
00360 int res = IntegerOps::cmp(x->number(), y->number());
00361 if (res < 0) return as_smiOop(-1);
00362 if (res > 0) return as_smiOop(1);
00363 return as_smiOop(0);
00364 }
00365
00366 PRIM_DECL_1(byteArrayPrimitives::largeIntegerToFloat, oop receiver) {
00367 PROLOGUE_1("largeIntegerToFloat", receiver);
00368 ASSERT_RECEIVER;
00369
00370 bool ok;
00371 double result = byteArrayOop(receiver)->number().as_double(ok);
00372
00373 if (!ok) return markSymbol(vmSymbols::conversion_failed());
00374
00375 BlockScavenge bs;
00376 return oopFactory::new_double(result);
00377 }
00378
00379 PRIM_DECL_2(byteArrayPrimitives::largeIntegerToString, oop receiver, oop base) {
00380 PROLOGUE_1("largeIntegerToString", receiver);
00381 ASSERT_RECEIVER;
00382
00383
00384 if (!base->is_smi())
00385 return markSymbol(vmSymbols::first_argument_has_wrong_type());
00386
00387 BlockScavenge bs;
00388
00389 byteArrayOop x = byteArrayOop(receiver);
00390 int length = IntegerOps::Integer_to_string_result_size_in_bytes(x->number(), smiOop(base)->value());
00391
00392 byteArrayOop result = oopFactory::new_byteArray(length);
00393
00394 IntegerOps::Integer_to_string(x->number(), smiOop(base)->value(), result->chars());
00395 return result;
00396 }
00397
00398 PRIM_DECL_1(byteArrayPrimitives::hash, oop receiver) {
00399 PROLOGUE_1("hash", receiver);
00400 ASSERT_RECEIVER;
00401 return as_smiOop(byteArrayOop(receiver)->hash_value());
00402 }