Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 22815014: MIPS: Remove platform-specific dead code for KeyedStores (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 Handle<GlobalObject>::cast(current), 1149 Handle<GlobalObject>::cast(current),
1150 name, 1150 name,
1151 scratch, 1151 scratch,
1152 miss); 1152 miss);
1153 } 1153 }
1154 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 1154 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
1155 } 1155 }
1156 } 1156 }
1157 1157
1158 1158
1159 // Convert and store int passed in register ival to IEEE 754 single precision
1160 // floating point value at memory location (dst + 4 * wordoffset)
1161 // If FPU is available use it for conversion.
1162 static void StoreIntAsFloat(MacroAssembler* masm,
1163 Register dst,
1164 Register wordoffset,
1165 Register ival,
1166 Register scratch1) {
1167 __ mtc1(ival, f0);
1168 __ cvt_s_w(f0, f0);
1169 __ sll(scratch1, wordoffset, 2);
1170 __ addu(scratch1, dst, scratch1);
1171 __ swc1(f0, MemOperand(scratch1, 0));
1172 }
1173
1174
1175 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1159 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1176 __ Jump(code, RelocInfo::CODE_TARGET); 1160 __ Jump(code, RelocInfo::CODE_TARGET);
1177 } 1161 }
1178 1162
1179 1163
1180 #undef __ 1164 #undef __
1181 #define __ ACCESS_MASM(masm()) 1165 #define __ ACCESS_MASM(masm())
1182 1166
1183 1167
1184 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1168 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
(...skipping 2037 matching lines...) Expand 10 before | Expand all | Expand 10 after
3222 3206
3223 // ---------- S t a t e -------------- 3207 // ---------- S t a t e --------------
3224 // -- ra : return address 3208 // -- ra : return address
3225 // -- a0 : key 3209 // -- a0 : key
3226 // -- a1 : receiver 3210 // -- a1 : receiver
3227 // ----------------------------------- 3211 // -----------------------------------
3228 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3212 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3229 } 3213 }
3230 3214
3231 3215
3232 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3233 Register key,
3234 Register scratch0,
3235 Register scratch1,
3236 FPURegister double_scratch0,
3237 FPURegister double_scratch1,
3238 Label* fail) {
3239 Label key_ok;
3240 // Check for smi or a smi inside a heap number. We convert the heap
3241 // number and check if the conversion is exact and fits into the smi
3242 // range.
3243 __ JumpIfSmi(key, &key_ok);
3244 __ CheckMap(key,
3245 scratch0,
3246 Heap::kHeapNumberMapRootIndex,
3247 fail,
3248 DONT_DO_SMI_CHECK);
3249 __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset));
3250 __ EmitFPUTruncate(kRoundToZero,
3251 scratch0,
3252 double_scratch0,
3253 at,
3254 double_scratch1,
3255 scratch1,
3256 kCheckForInexactConversion);
3257
3258 __ Branch(fail, ne, scratch1, Operand(zero_reg));
3259
3260 __ SmiTagCheckOverflow(key, scratch0, scratch1);
3261 __ BranchOnOverflow(fail, scratch1);
3262 __ bind(&key_ok);
3263 }
3264
3265
3266 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3267 MacroAssembler* masm,
3268 ElementsKind elements_kind) {
3269 // ---------- S t a t e --------------
3270 // -- a0 : value
3271 // -- a1 : key
3272 // -- a2 : receiver
3273 // -- ra : return address
3274 // -----------------------------------
3275
3276 Label slow, check_heap_number, miss_force_generic;
3277
3278 // Register usage.
3279 Register value = a0;
3280 Register key = a1;
3281 Register receiver = a2;
3282 // a3 mostly holds the elements array or the destination external array.
3283
3284 // This stub is meant to be tail-jumped to, the receiver must already
3285 // have been verified by the caller to not be a smi.
3286
3287 // Check that the key is a smi or a heap number convertible to a smi.
3288 GenerateSmiKeyCheck(masm, key, t0, t1, f2, f4, &miss_force_generic);
3289
3290 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3291
3292 // Check that the index is in range.
3293 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset));
3294 // Unsigned comparison catches both negative and too-large values.
3295 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1));
3296
3297 // Handle both smis and HeapNumbers in the fast path. Go to the
3298 // runtime for all other kinds of values.
3299 // a3: external array.
3300
3301 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
3302 // Double to pixel conversion is only implemented in the runtime for now.
3303 __ JumpIfNotSmi(value, &slow);
3304 } else {
3305 __ JumpIfNotSmi(value, &check_heap_number);
3306 }
3307 __ SmiUntag(t1, value);
3308 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
3309
3310 // a3: base pointer of external storage.
3311 // t1: value (integer).
3312
3313 switch (elements_kind) {
3314 case EXTERNAL_PIXEL_ELEMENTS: {
3315 // Clamp the value to [0..255].
3316 // v0 is used as a scratch register here.
3317 Label done;
3318 __ li(v0, Operand(255));
3319 // Normal branch: nop in delay slot.
3320 __ Branch(&done, gt, t1, Operand(v0));
3321 // Use delay slot in this branch.
3322 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg));
3323 __ mov(v0, zero_reg); // In delay slot.
3324 __ mov(v0, t1); // Value is in range 0..255.
3325 __ bind(&done);
3326 __ mov(t1, v0);
3327
3328 __ srl(t8, key, 1);
3329 __ addu(t8, a3, t8);
3330 __ sb(t1, MemOperand(t8, 0));
3331 }
3332 break;
3333 case EXTERNAL_BYTE_ELEMENTS:
3334 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3335 __ srl(t8, key, 1);
3336 __ addu(t8, a3, t8);
3337 __ sb(t1, MemOperand(t8, 0));
3338 break;
3339 case EXTERNAL_SHORT_ELEMENTS:
3340 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3341 __ addu(t8, a3, key);
3342 __ sh(t1, MemOperand(t8, 0));
3343 break;
3344 case EXTERNAL_INT_ELEMENTS:
3345 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3346 __ sll(t8, key, 1);
3347 __ addu(t8, a3, t8);
3348 __ sw(t1, MemOperand(t8, 0));
3349 break;
3350 case EXTERNAL_FLOAT_ELEMENTS:
3351 // Perform int-to-float conversion and store to memory.
3352 __ SmiUntag(t0, key);
3353 StoreIntAsFloat(masm, a3, t0, t1, t2);
3354 break;
3355 case EXTERNAL_DOUBLE_ELEMENTS:
3356 __ sll(t8, key, 2);
3357 __ addu(a3, a3, t8);
3358 // a3: effective address of the double element
3359 FloatingPointHelper::Destination destination;
3360 destination = FloatingPointHelper::kFPURegisters;
3361 FloatingPointHelper::ConvertIntToDouble(
3362 masm, t1, destination,
3363 f0, t2, t3, // These are: double_dst, dst_mantissa, dst_exponent.
3364 t0, f2); // These are: scratch2, single_scratch.
3365 __ sdc1(f0, MemOperand(a3, 0));
3366 break;
3367 case FAST_ELEMENTS:
3368 case FAST_SMI_ELEMENTS:
3369 case FAST_DOUBLE_ELEMENTS:
3370 case FAST_HOLEY_ELEMENTS:
3371 case FAST_HOLEY_SMI_ELEMENTS:
3372 case FAST_HOLEY_DOUBLE_ELEMENTS:
3373 case DICTIONARY_ELEMENTS:
3374 case NON_STRICT_ARGUMENTS_ELEMENTS:
3375 UNREACHABLE();
3376 break;
3377 }
3378
3379 // Entry registers are intact, a0 holds the value which is the return value.
3380 __ Ret(USE_DELAY_SLOT);
3381 __ mov(v0, a0);
3382
3383 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3384 // a3: external array.
3385 __ bind(&check_heap_number);
3386 __ GetObjectType(value, t1, t2);
3387 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE));
3388
3389 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
3390
3391 // a3: base pointer of external storage.
3392
3393 // The WebGL specification leaves the behavior of storing NaN and
3394 // +/-Infinity into integer arrays basically undefined. For more
3395 // reproducible behavior, convert these to zero.
3396
3397
3398 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset));
3399
3400 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3401 __ cvt_s_d(f0, f0);
3402 __ sll(t8, key, 1);
3403 __ addu(t8, a3, t8);
3404 __ swc1(f0, MemOperand(t8, 0));
3405 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3406 __ sll(t8, key, 2);
3407 __ addu(t8, a3, t8);
3408 __ sdc1(f0, MemOperand(t8, 0));
3409 } else {
3410 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5);
3411
3412 switch (elements_kind) {
3413 case EXTERNAL_BYTE_ELEMENTS:
3414 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3415 __ srl(t8, key, 1);
3416 __ addu(t8, a3, t8);
3417 __ sb(t3, MemOperand(t8, 0));
3418 break;
3419 case EXTERNAL_SHORT_ELEMENTS:
3420 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3421 __ addu(t8, a3, key);
3422 __ sh(t3, MemOperand(t8, 0));
3423 break;
3424 case EXTERNAL_INT_ELEMENTS:
3425 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3426 __ sll(t8, key, 1);
3427 __ addu(t8, a3, t8);
3428 __ sw(t3, MemOperand(t8, 0));
3429 break;
3430 case EXTERNAL_PIXEL_ELEMENTS:
3431 case EXTERNAL_FLOAT_ELEMENTS:
3432 case EXTERNAL_DOUBLE_ELEMENTS:
3433 case FAST_ELEMENTS:
3434 case FAST_SMI_ELEMENTS:
3435 case FAST_DOUBLE_ELEMENTS:
3436 case FAST_HOLEY_ELEMENTS:
3437 case FAST_HOLEY_SMI_ELEMENTS:
3438 case FAST_HOLEY_DOUBLE_ELEMENTS:
3439 case DICTIONARY_ELEMENTS:
3440 case NON_STRICT_ARGUMENTS_ELEMENTS:
3441 UNREACHABLE();
3442 break;
3443 }
3444 }
3445
3446 // Entry registers are intact, a0 holds the value
3447 // which is the return value.
3448 __ Ret(USE_DELAY_SLOT);
3449 __ mov(v0, a0);
3450 }
3451
3452 // Slow case, key and receiver still in a0 and a1.
3453 __ bind(&slow);
3454 __ IncrementCounter(
3455 masm->isolate()->counters()->keyed_load_external_array_slow(),
3456 1, a2, a3);
3457 // Entry registers are intact.
3458 // ---------- S t a t e --------------
3459 // -- ra : return address
3460 // -- a0 : key
3461 // -- a1 : receiver
3462 // -----------------------------------
3463 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3464
3465 // Miss case, call the runtime.
3466 __ bind(&miss_force_generic);
3467
3468 // ---------- S t a t e --------------
3469 // -- ra : return address
3470 // -- a0 : key
3471 // -- a1 : receiver
3472 // -----------------------------------
3473 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3474 }
3475
3476
3477 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3478 MacroAssembler* masm,
3479 bool is_js_array,
3480 ElementsKind elements_kind,
3481 KeyedAccessStoreMode store_mode) {
3482 // ----------- S t a t e -------------
3483 // -- a0 : value
3484 // -- a1 : key
3485 // -- a2 : receiver
3486 // -- ra : return address
3487 // -- a3 : scratch
3488 // -- a4 : scratch (elements)
3489 // -----------------------------------
3490 Label miss_force_generic, transition_elements_kind, grow, slow;
3491 Label finish_store, check_capacity;
3492
3493 Register value_reg = a0;
3494 Register key_reg = a1;
3495 Register receiver_reg = a2;
3496 Register scratch = t0;
3497 Register elements_reg = a3;
3498 Register length_reg = t1;
3499 Register scratch2 = t2;
3500
3501 // This stub is meant to be tail-jumped to, the receiver must already
3502 // have been verified by the caller to not be a smi.
3503
3504 // Check that the key is a smi or a heap number convertible to a smi.
3505 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic);
3506
3507 if (IsFastSmiElementsKind(elements_kind)) {
3508 __ JumpIfNotSmi(value_reg, &transition_elements_kind);
3509 }
3510
3511 // Check that the key is within bounds.
3512 __ lw(elements_reg,
3513 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3514 if (is_js_array) {
3515 __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3516 } else {
3517 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
3518 }
3519 // Compare smis.
3520 if (is_js_array && IsGrowStoreMode(store_mode)) {
3521 __ Branch(&grow, hs, key_reg, Operand(scratch));
3522 } else {
3523 __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch));
3524 }
3525
3526 // Make sure elements is a fast element array, not 'cow'.
3527 __ CheckMap(elements_reg,
3528 scratch,
3529 Heap::kFixedArrayMapRootIndex,
3530 &miss_force_generic,
3531 DONT_DO_SMI_CHECK);
3532
3533 __ bind(&finish_store);
3534
3535 if (IsFastSmiElementsKind(elements_kind)) {
3536 __ Addu(scratch,
3537 elements_reg,
3538 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3539 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
3540 __ sll(scratch2, key_reg, kPointerSizeLog2 - kSmiTagSize);
3541 __ Addu(scratch, scratch, scratch2);
3542 __ sw(value_reg, MemOperand(scratch));
3543 } else {
3544 ASSERT(IsFastObjectElementsKind(elements_kind));
3545 __ Addu(scratch,
3546 elements_reg,
3547 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3548 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
3549 __ sll(scratch2, key_reg, kPointerSizeLog2 - kSmiTagSize);
3550 __ Addu(scratch, scratch, scratch2);
3551 __ sw(value_reg, MemOperand(scratch));
3552 __ mov(receiver_reg, value_reg);
3553 __ RecordWrite(elements_reg, // Object.
3554 scratch, // Address.
3555 receiver_reg, // Value.
3556 kRAHasNotBeenSaved,
3557 kDontSaveFPRegs);
3558 }
3559 // value_reg (a0) is preserved.
3560 // Done.
3561 __ Ret();
3562
3563 __ bind(&miss_force_generic);
3564 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3565
3566 __ bind(&transition_elements_kind);
3567 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3568
3569 if (is_js_array && IsGrowStoreMode(store_mode)) {
3570 // Grow the array by a single element if possible.
3571 __ bind(&grow);
3572
3573 // Make sure the array is only growing by a single element, anything else
3574 // must be handled by the runtime.
3575 __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch));
3576
3577 // Check for the empty array, and preallocate a small backing store if
3578 // possible.
3579 __ lw(length_reg,
3580 FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3581 __ lw(elements_reg,
3582 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3583 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
3584 __ Branch(&check_capacity, ne, elements_reg, Operand(at));
3585
3586 int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
3587 __ Allocate(size, elements_reg, scratch, scratch2, &slow, TAG_OBJECT);
3588
3589 __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex);
3590 __ sw(scratch, FieldMemOperand(elements_reg, JSObject::kMapOffset));
3591 __ li(scratch, Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
3592 __ sw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
3593 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
3594 for (int i = 1; i < JSArray::kPreallocatedArrayElements; ++i) {
3595 __ sw(scratch, FieldMemOperand(elements_reg, FixedArray::SizeFor(i)));
3596 }
3597
3598 // Store the element at index zero.
3599 __ sw(value_reg, FieldMemOperand(elements_reg, FixedArray::SizeFor(0)));
3600
3601 // Install the new backing store in the JSArray.
3602 __ sw(elements_reg,
3603 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3604 __ RecordWriteField(receiver_reg, JSObject::kElementsOffset, elements_reg,
3605 scratch, kRAHasNotBeenSaved, kDontSaveFPRegs,
3606 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3607
3608 // Increment the length of the array.
3609 __ li(length_reg, Operand(Smi::FromInt(1)));
3610 __ Ret(USE_DELAY_SLOT);
3611 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3612
3613 __ bind(&check_capacity);
3614 // Check for cow elements, in general they are not handled by this stub
3615 __ CheckMap(elements_reg,
3616 scratch,
3617 Heap::kFixedCOWArrayMapRootIndex,
3618 &miss_force_generic,
3619 DONT_DO_SMI_CHECK);
3620
3621 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
3622 __ Branch(&slow, hs, length_reg, Operand(scratch));
3623
3624 // Grow the array and finish the store.
3625 __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1)));
3626 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3627 __ jmp(&finish_store);
3628
3629 __ bind(&slow);
3630 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3631 }
3632 }
3633
3634
3635 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3636 MacroAssembler* masm,
3637 bool is_js_array,
3638 KeyedAccessStoreMode store_mode) {
3639 // ----------- S t a t e -------------
3640 // -- a0 : value
3641 // -- a1 : key
3642 // -- a2 : receiver
3643 // -- ra : return address
3644 // -- a3 : scratch (elements backing store)
3645 // -- t0 : scratch (elements_reg)
3646 // -- t1 : scratch (mantissa_reg)
3647 // -- t2 : scratch (exponent_reg)
3648 // -- t3 : scratch4
3649 // -- t4 : scratch
3650 // -----------------------------------
3651 Label miss_force_generic, transition_elements_kind, grow, slow;
3652 Label finish_store, check_capacity;
3653
3654 Register value_reg = a0;
3655 Register key_reg = a1;
3656 Register receiver_reg = a2;
3657 Register elements_reg = a3;
3658 Register scratch1 = t0;
3659 Register scratch2 = t1;
3660 Register scratch3 = t2;
3661 Register scratch4 = t3;
3662 Register scratch5 = t4;
3663 Register length_reg = t3;
3664
3665 // This stub is meant to be tail-jumped to, the receiver must already
3666 // have been verified by the caller to not be a smi.
3667
3668 // Check that the key is a smi or a heap number convertible to a smi.
3669 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic);
3670
3671 __ lw(elements_reg,
3672 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3673
3674 // Check that the key is within bounds.
3675 if (is_js_array) {
3676 __ lw(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3677 } else {
3678 __ lw(scratch1,
3679 FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
3680 }
3681 // Compare smis, unsigned compare catches both negative and out-of-bound
3682 // indexes.
3683 if (IsGrowStoreMode(store_mode)) {
3684 __ Branch(&grow, hs, key_reg, Operand(scratch1));
3685 } else {
3686 __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch1));
3687 }
3688
3689 __ bind(&finish_store);
3690
3691 __ StoreNumberToDoubleElements(value_reg,
3692 key_reg,
3693 // All registers after this are overwritten.
3694 elements_reg,
3695 scratch1,
3696 scratch2,
3697 scratch3,
3698 scratch4,
3699 &transition_elements_kind);
3700
3701 __ Ret(USE_DELAY_SLOT);
3702 __ mov(v0, value_reg); // In delay slot.
3703
3704 // Handle store cache miss, replacing the ic with the generic stub.
3705 __ bind(&miss_force_generic);
3706 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3707
3708 __ bind(&transition_elements_kind);
3709 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3710
3711 if (is_js_array && IsGrowStoreMode(store_mode)) {
3712 // Grow the array by a single element if possible.
3713 __ bind(&grow);
3714
3715 // Make sure the array is only growing by a single element, anything else
3716 // must be handled by the runtime.
3717 __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch1));
3718
3719 // Transition on values that can't be stored in a FixedDoubleArray.
3720 Label value_is_smi;
3721 __ JumpIfSmi(value_reg, &value_is_smi);
3722 __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
3723 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3724 __ Branch(&transition_elements_kind, ne, scratch1, Operand(at));
3725 __ bind(&value_is_smi);
3726
3727 // Check for the empty array, and preallocate a small backing store if
3728 // possible.
3729 __ lw(length_reg,
3730 FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3731 __ lw(elements_reg,
3732 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3733 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
3734 __ Branch(&check_capacity, ne, elements_reg, Operand(at));
3735
3736 int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements);
3737 __ Allocate(size, elements_reg, scratch1, scratch2, &slow, TAG_OBJECT);
3738
3739 // Initialize the new FixedDoubleArray.
3740 __ LoadRoot(scratch1, Heap::kFixedDoubleArrayMapRootIndex);
3741 __ sw(scratch1, FieldMemOperand(elements_reg, JSObject::kMapOffset));
3742 __ li(scratch1, Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
3743 __ sw(scratch1,
3744 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset));
3745
3746 __ mov(scratch1, elements_reg);
3747 __ StoreNumberToDoubleElements(value_reg,
3748 key_reg,
3749 // All registers after this are overwritten.
3750 scratch1,
3751 scratch2,
3752 scratch3,
3753 scratch4,
3754 scratch5,
3755 &transition_elements_kind);
3756
3757 __ li(scratch1, Operand(kHoleNanLower32));
3758 __ li(scratch2, Operand(kHoleNanUpper32));
3759 for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) {
3760 int offset = FixedDoubleArray::OffsetOfElementAt(i);
3761 __ sw(scratch1, FieldMemOperand(elements_reg, offset));
3762 __ sw(scratch2, FieldMemOperand(elements_reg, offset + kPointerSize));
3763 }
3764
3765 // Install the new backing store in the JSArray.
3766 __ sw(elements_reg,
3767 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3768 __ RecordWriteField(receiver_reg, JSObject::kElementsOffset, elements_reg,
3769 scratch1, kRAHasNotBeenSaved, kDontSaveFPRegs,
3770 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3771
3772 // Increment the length of the array.
3773 __ li(length_reg, Operand(Smi::FromInt(1)));
3774 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3775 __ Ret(USE_DELAY_SLOT);
3776 __ lw(elements_reg,
3777 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3778
3779 __ bind(&check_capacity);
3780 // Make sure that the backing store can hold additional elements.
3781 __ lw(scratch1,
3782 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset));
3783 __ Branch(&slow, hs, length_reg, Operand(scratch1));
3784
3785 // Grow the array and finish the store.
3786 __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1)));
3787 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3788 __ jmp(&finish_store);
3789
3790 __ bind(&slow);
3791 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3792 }
3793 }
3794
3795
3796 #undef __ 3216 #undef __
3797 3217
3798 } } // namespace v8::internal 3218 } } // namespace v8::internal
3799 3219
3800 #endif // V8_TARGET_ARCH_MIPS 3220 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698