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

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 2357323003: [ic][ia32][x87] Don't push/pop value/slot/vector in store handlers. (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x87/macro-assembler-x87.h » ('j') | 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 3336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3347 // value is on the stack already. 3347 // value is on the stack already.
3348 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, 3348 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
3349 Register key, Register vector, 3349 Register key, Register vector,
3350 Register slot, Register feedback, 3350 Register slot, Register feedback,
3351 bool is_polymorphic, Label* miss) { 3351 bool is_polymorphic, Label* miss) {
3352 // feedback initially contains the feedback array 3352 // feedback initially contains the feedback array
3353 Label next, next_loop, prepare_next; 3353 Label next, next_loop, prepare_next;
3354 Label load_smi_map, compare_map; 3354 Label load_smi_map, compare_map;
3355 Label start_polymorphic; 3355 Label start_polymorphic;
3356 Label pop_and_miss; 3356 Label pop_and_miss;
3357 ExternalReference virtual_register =
3358 ExternalReference::virtual_handler_register(masm->isolate());
3359 3357
3360 __ push(receiver); 3358 __ push(receiver);
3361 __ push(vector); 3359 // Value, vector and slot are passed on the stack, so no need to save/restore
3360 // them.
3362 3361
3363 Register receiver_map = receiver; 3362 Register receiver_map = receiver;
3364 Register cached_map = vector; 3363 Register cached_map = vector;
3365 3364
3366 // Receiver might not be a heap object. 3365 // Receiver might not be a heap object.
3367 __ JumpIfSmi(receiver, &load_smi_map); 3366 __ JumpIfSmi(receiver, &load_smi_map);
3368 __ mov(receiver_map, FieldOperand(receiver, 0)); 3367 __ mov(receiver_map, FieldOperand(receiver, 0));
3369 __ bind(&compare_map); 3368 __ bind(&compare_map);
3370 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0))); 3369 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
3371 3370
3372 // A named keyed store might have a 2 element array, all other cases can count 3371 // A named keyed store might have a 2 element array, all other cases can count
3373 // on an array with at least 2 {map, handler} pairs, so they can go right 3372 // on an array with at least 2 {map, handler} pairs, so they can go right
3374 // into polymorphic array handling. 3373 // into polymorphic array handling.
3375 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3374 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3376 __ j(not_equal, &start_polymorphic); 3375 __ j(not_equal, &start_polymorphic);
3377 3376
3378 // found, now call handler. 3377 // found, now call handler.
3379 Register handler = feedback; 3378 Register handler = feedback;
3380 DCHECK(handler.is(StoreWithVectorDescriptor::ValueRegister())); 3379 DCHECK(handler.is(StoreWithVectorDescriptor::ValueRegister()));
3381 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); 3380 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
3382 __ pop(vector);
3383 __ pop(receiver); 3381 __ pop(receiver);
3384 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); 3382 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
3385 __ mov(Operand::StaticVariable(virtual_register), handler); 3383 __ jmp(handler);
3386 __ pop(handler); // Pop "value".
3387 __ jmp(Operand::StaticVariable(virtual_register));
3388 3384
3389 // Polymorphic, we have to loop from 2 to N 3385 // Polymorphic, we have to loop from 2 to N
3390 __ bind(&start_polymorphic); 3386 __ bind(&start_polymorphic);
3391 __ push(key); 3387 __ push(key);
3392 Register counter = key; 3388 Register counter = key;
3393 __ mov(counter, Immediate(Smi::FromInt(2))); 3389 __ mov(counter, Immediate(Smi::FromInt(2)));
3394 3390
3395 if (!is_polymorphic) { 3391 if (!is_polymorphic) {
3396 // If is_polymorphic is false, we may only have a two element array. 3392 // If is_polymorphic is false, we may only have a two element array.
3397 // Check against length now in that case. 3393 // Check against length now in that case.
3398 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 3394 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
3399 __ j(greater_equal, &pop_and_miss); 3395 __ j(greater_equal, &pop_and_miss);
3400 } 3396 }
3401 3397
3402 __ bind(&next_loop); 3398 __ bind(&next_loop);
3403 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 3399 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
3404 FixedArray::kHeaderSize)); 3400 FixedArray::kHeaderSize));
3405 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3401 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3406 __ j(not_equal, &prepare_next); 3402 __ j(not_equal, &prepare_next);
3407 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, 3403 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size,
3408 FixedArray::kHeaderSize + kPointerSize)); 3404 FixedArray::kHeaderSize + kPointerSize));
3409 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); 3405 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
3410 __ pop(key); 3406 __ pop(key);
3411 __ pop(vector);
3412 __ pop(receiver); 3407 __ pop(receiver);
3413 __ mov(Operand::StaticVariable(virtual_register), handler); 3408 __ jmp(handler);
3414 __ pop(handler); // Pop "value".
3415 __ jmp(Operand::StaticVariable(virtual_register));
3416 3409
3417 __ bind(&prepare_next); 3410 __ bind(&prepare_next);
3418 __ add(counter, Immediate(Smi::FromInt(2))); 3411 __ add(counter, Immediate(Smi::FromInt(2)));
3419 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 3412 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
3420 __ j(less, &next_loop); 3413 __ j(less, &next_loop);
3421 3414
3422 // We exhausted our array of map handler pairs. 3415 // We exhausted our array of map handler pairs.
3423 __ bind(&pop_and_miss); 3416 __ bind(&pop_and_miss);
3424 __ pop(key); 3417 __ pop(key);
3425 __ pop(vector);
3426 __ pop(receiver); 3418 __ pop(receiver);
3427 __ jmp(miss); 3419 __ jmp(miss);
3428 3420
3429 __ bind(&load_smi_map); 3421 __ bind(&load_smi_map);
3430 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); 3422 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
3431 __ jmp(&compare_map); 3423 __ jmp(&compare_map);
3432 } 3424 }
3433 3425
3434 3426
3435 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, 3427 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
3436 Register key, Register vector, 3428 Register key, Register vector,
3437 Register slot, Register weak_cell, 3429 Register slot, Register weak_cell,
3438 Label* miss) { 3430 Label* miss) {
3439 // The store ic value is on the stack. 3431 // The store ic value is on the stack.
3440 DCHECK(weak_cell.is(StoreWithVectorDescriptor::ValueRegister())); 3432 DCHECK(weak_cell.is(StoreWithVectorDescriptor::ValueRegister()));
3441 ExternalReference virtual_register =
3442 ExternalReference::virtual_handler_register(masm->isolate());
3443 3433
3444 // feedback initially contains the feedback array 3434 // feedback initially contains the feedback array
3445 Label compare_smi_map; 3435 Label compare_smi_map;
3446 3436
3447 // Move the weak map into the weak_cell register. 3437 // Move the weak map into the weak_cell register.
3448 Register ic_map = weak_cell; 3438 Register ic_map = weak_cell;
3449 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); 3439 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset));
3450 3440
3451 // Receiver might not be a heap object. 3441 // Receiver might not be a heap object.
3452 __ JumpIfSmi(receiver, &compare_smi_map); 3442 __ JumpIfSmi(receiver, &compare_smi_map);
3453 __ cmp(ic_map, FieldOperand(receiver, 0)); 3443 __ cmp(ic_map, FieldOperand(receiver, 0));
3454 __ j(not_equal, miss); 3444 __ j(not_equal, miss);
3455 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, 3445 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
3456 FixedArray::kHeaderSize + kPointerSize)); 3446 FixedArray::kHeaderSize + kPointerSize));
3457 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); 3447 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
3458 // Put the store ic value back in it's register.
3459 __ mov(Operand::StaticVariable(virtual_register), weak_cell);
3460 __ pop(weak_cell); // Pop "value".
3461 // jump to the handler. 3448 // jump to the handler.
3462 __ jmp(Operand::StaticVariable(virtual_register)); 3449 __ jmp(weak_cell);
3463 3450
3464 // In microbenchmarks, it made sense to unroll this code so that the call to 3451 // In microbenchmarks, it made sense to unroll this code so that the call to
3465 // the handler is duplicated for a HeapObject receiver and a Smi receiver. 3452 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
3466 __ bind(&compare_smi_map); 3453 __ bind(&compare_smi_map);
3467 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); 3454 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex);
3468 __ j(not_equal, miss); 3455 __ j(not_equal, miss);
3469 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, 3456 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
3470 FixedArray::kHeaderSize + kPointerSize)); 3457 FixedArray::kHeaderSize + kPointerSize));
3471 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); 3458 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
3472 __ mov(Operand::StaticVariable(virtual_register), weak_cell);
3473 __ pop(weak_cell); // Pop "value".
3474 // jump to the handler. 3459 // jump to the handler.
3475 __ jmp(Operand::StaticVariable(virtual_register)); 3460 __ jmp(weak_cell);
3476 } 3461 }
3477 3462
3478 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 3463 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
3479 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx 3464 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx
3480 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx 3465 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx
3481 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax 3466 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax
3482 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx 3467 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx
3483 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi 3468 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi
3484 Label miss; 3469 Label miss;
3485 3470
3486 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { 3471 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) {
3487 // Current stack layout: 3472 // Current stack layout:
3488 // - esp[8] -- value 3473 // - esp[8] -- value
3489 // - esp[4] -- slot 3474 // - esp[4] -- slot
3490 // - esp[0] -- return address 3475 // - esp[0] -- return address
3491 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); 3476 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2);
3492 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); 3477 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
3493 if (in_frame) { 3478 if (in_frame) {
3494 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); 3479 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor");
3495 // If the vector is not on the stack, then insert the vector beneath 3480 // If the vector is not on the stack, then insert the vector beneath
3496 // return address in order to prepare for calling handler with 3481 // return address in order to prepare for calling handler with
3497 // StoreWithVector calling convention. 3482 // StoreWithVector calling convention.
3498 __ push(Operand(esp, 0)); 3483 __ push(Operand(esp, 0));
3499 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); 3484 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
3500 __ RecordComment("]"); 3485 __ RecordComment("]");
3501 } else { 3486 } else {
3502 __ mov(vector, Operand(esp, 1 * kPointerSize)); 3487 __ mov(vector, Operand(esp, 1 * kPointerSize));
3503 } 3488 }
3504 __ mov(slot, Operand(esp, 2 * kPointerSize)); 3489 __ mov(slot, Operand(esp, 2 * kPointerSize));
3505 __ mov(value, Operand(esp, 3 * kPointerSize));
3506 } 3490 }
3507 3491
3508 __ push(value);
3509
3510 Register scratch = value; 3492 Register scratch = value;
3511 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 3493 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
3512 FixedArray::kHeaderSize)); 3494 FixedArray::kHeaderSize));
3513 3495
3514 // Is it a weak cell? 3496 // Is it a weak cell?
3515 Label try_array; 3497 Label try_array;
3516 Label not_array, smi_key, key_okay; 3498 Label not_array, smi_key, key_okay;
3517 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); 3499 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
3518 __ j(not_equal, &try_array); 3500 __ j(not_equal, &try_array);
3519 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); 3501 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
3520 3502
3521 // Is it a fixed array? 3503 // Is it a fixed array?
3522 __ bind(&try_array); 3504 __ bind(&try_array);
3523 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); 3505 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
3524 __ j(not_equal, &not_array); 3506 __ j(not_equal, &not_array);
3525 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, true, 3507 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, true,
3526 &miss); 3508 &miss);
3527 3509
3528 __ bind(&not_array); 3510 __ bind(&not_array);
3529 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); 3511 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
3530 __ j(not_equal, &miss); 3512 __ j(not_equal, &miss);
3531 3513
3532 __ pop(value);
3533 __ push(slot);
3534 __ push(vector);
3535 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, slot, 3514 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, slot,
3536 no_reg); 3515 no_reg);
3537 __ pop(vector);
3538 __ pop(slot);
3539 Label no_pop_miss;
3540 __ jmp(&no_pop_miss);
3541
3542 __ bind(&miss); 3516 __ bind(&miss);
3543 __ pop(value);
3544 __ bind(&no_pop_miss);
3545 StoreIC::GenerateMiss(masm); 3517 StoreIC::GenerateMiss(masm);
3546 } 3518 }
3547 3519
3548 void KeyedStoreICStub::Generate(MacroAssembler* masm) { 3520 void KeyedStoreICStub::Generate(MacroAssembler* masm) {
3549 GenerateImpl(masm, false); 3521 GenerateImpl(masm, false);
3550 } 3522 }
3551 3523
3552 void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { 3524 void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) {
3553 GenerateImpl(masm, true); 3525 GenerateImpl(masm, true);
3554 } 3526 }
3555 3527
3556 3528
3557 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, 3529 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
3558 Register receiver, Register key, 3530 Register receiver, Register key,
3559 Register vector, Register slot, 3531 Register vector, Register slot,
3560 Register feedback, Label* miss) { 3532 Register feedback, Label* miss) {
3561 // feedback initially contains the feedback array 3533 // feedback initially contains the feedback array
3562 Label next, next_loop, prepare_next; 3534 Label next, next_loop, prepare_next;
3563 Label load_smi_map, compare_map; 3535 Label load_smi_map, compare_map;
3564 Label transition_call; 3536 Label transition_call;
3565 Label pop_and_miss; 3537 Label pop_and_miss;
3566 ExternalReference virtual_register =
3567 ExternalReference::virtual_handler_register(masm->isolate());
3568 ExternalReference virtual_slot =
3569 ExternalReference::virtual_slot_register(masm->isolate());
3570 3538
3571 __ push(receiver); 3539 __ push(receiver);
3572 __ push(vector); 3540 // Value, vector and slot are passed on the stack, so no need to save/restore
3541 // them.
3573 3542
3574 Register receiver_map = receiver; 3543 Register receiver_map = receiver;
3575 Register cached_map = vector; 3544 Register cached_map = vector;
3576 Register value = StoreDescriptor::ValueRegister();
3577 3545
3578 // Receiver might not be a heap object. 3546 // Receiver might not be a heap object.
3579 __ JumpIfSmi(receiver, &load_smi_map); 3547 __ JumpIfSmi(receiver, &load_smi_map);
3580 __ mov(receiver_map, FieldOperand(receiver, 0)); 3548 __ mov(receiver_map, FieldOperand(receiver, 0));
3581 __ bind(&compare_map); 3549 __ bind(&compare_map);
3582 3550
3583 // Polymorphic, we have to loop from 0 to N - 1 3551 // Polymorphic, we have to loop from 0 to N - 1
3584 __ push(key); 3552 __ push(key);
3585 // Current stack layout: 3553 // Current stack layout:
3586 // - esp[0] -- key 3554 // - esp[0] -- key
3555 // - esp[4] -- receiver
3556 // - esp[8] -- return address
3557 // - esp[12] -- vector
3558 // - esp[16] -- slot
3559 // - esp[20] -- value
3560 //
3561 // Required stack layout for handler call (see StoreWithVectorDescriptor):
3562 // - esp[0] -- return address
3587 // - esp[4] -- vector 3563 // - esp[4] -- vector
3588 // - esp[8] -- receiver 3564 // - esp[8] -- slot
3589 // - esp[12] -- value 3565 // - esp[12] -- value
3590 // - esp[16] -- return address 3566 // - receiver, key, handler in registers.
3591 //
3592 // Required stack layout for handler call:
3593 // - esp[0] -- return address
3594 // - receiver, key, value, vector, slot in registers.
3595 // - handler in virtual register.
3596 Register counter = key; 3567 Register counter = key;
3597 __ mov(counter, Immediate(Smi::FromInt(0))); 3568 __ mov(counter, Immediate(Smi::FromInt(0)));
3598 __ bind(&next_loop); 3569 __ bind(&next_loop);
3599 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 3570 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
3600 FixedArray::kHeaderSize)); 3571 FixedArray::kHeaderSize));
3601 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3572 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3602 __ j(not_equal, &prepare_next); 3573 __ j(not_equal, &prepare_next);
3603 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 3574 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
3604 FixedArray::kHeaderSize + kPointerSize)); 3575 FixedArray::kHeaderSize + kPointerSize));
3605 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); 3576 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex);
3606 __ j(not_equal, &transition_call); 3577 __ j(not_equal, &transition_call);
3607 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, 3578 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
3608 FixedArray::kHeaderSize + 2 * kPointerSize)); 3579 FixedArray::kHeaderSize + 2 * kPointerSize));
3609 __ pop(key); 3580 __ pop(key);
3610 __ pop(vector);
3611 __ pop(receiver); 3581 __ pop(receiver);
3612 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); 3582 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
3613 __ mov(Operand::StaticVariable(virtual_register), feedback); 3583 __ jmp(feedback);
3614 __ pop(value);
3615
3616 // Call store handler using StoreWithVectorDescriptor calling convention.
3617 __ jmp(Operand::StaticVariable(virtual_register));
3618 3584
3619 __ bind(&transition_call); 3585 __ bind(&transition_call);
3620 // Current stack layout: 3586 // Current stack layout:
3621 // - esp[0] -- key 3587 // - esp[0] -- key
3588 // - esp[4] -- receiver
3589 // - esp[8] -- return address
3590 // - esp[12] -- vector
3591 // - esp[16] -- slot
3592 // - esp[20] -- value
3593 //
3594 // Required stack layout for handler call (see StoreTransitionDescriptor):
3595 // - esp[0] -- return address
3622 // - esp[4] -- vector 3596 // - esp[4] -- vector
3623 // - esp[8] -- receiver 3597 // - esp[8] -- slot
3624 // - esp[12] -- value 3598 // - esp[12] -- value
3625 // - esp[16] -- return address 3599 // - receiver, key, map, handler in registers.
3626 //
3627 // Required stack layout for handler call:
3628 // - esp[0] -- return address
3629 // - receiver, key, value, map, vector in registers.
3630 // - handler and slot in virtual registers.
3631 __ mov(Operand::StaticVariable(virtual_slot), slot);
3632 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, 3600 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
3633 FixedArray::kHeaderSize + 2 * kPointerSize)); 3601 FixedArray::kHeaderSize + 2 * kPointerSize));
3634 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); 3602 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
3635 __ mov(Operand::StaticVariable(virtual_register), feedback);
3636 3603
3637 __ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3604 __ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3638 // The weak cell may have been cleared. 3605 // The weak cell may have been cleared.
3639 __ JumpIfSmi(cached_map, &pop_and_miss); 3606 __ JumpIfSmi(cached_map, &pop_and_miss);
3640 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister())); 3607 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister()));
3641 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map); 3608 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map);
3642 3609
3643 // Call store transition handler using StoreTransitionDescriptor calling 3610 // Call store transition handler using StoreTransitionDescriptor calling
3644 // convention. 3611 // convention.
3645 __ pop(key); 3612 __ pop(key);
3646 __ pop(vector);
3647 __ pop(receiver); 3613 __ pop(receiver);
3648 __ pop(value);
3649 // Ensure that the transition handler we are going to call has the same 3614 // Ensure that the transition handler we are going to call has the same
3650 // number of stack arguments which means that we don't have to adapt them 3615 // number of stack arguments which means that we don't have to adapt them
3651 // before the call. 3616 // before the call.
3652 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); 3617 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
3653 STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3); 3618 STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3);
3654 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - 3619 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
3655 StoreWithVectorDescriptor::kValue == 3620 StoreWithVectorDescriptor::kValue ==
3656 StoreTransitionDescriptor::kParameterCount - 3621 StoreTransitionDescriptor::kParameterCount -
3657 StoreTransitionDescriptor::kValue); 3622 StoreTransitionDescriptor::kValue);
3658 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - 3623 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
3659 StoreWithVectorDescriptor::kSlot == 3624 StoreWithVectorDescriptor::kSlot ==
3660 StoreTransitionDescriptor::kParameterCount - 3625 StoreTransitionDescriptor::kParameterCount -
3661 StoreTransitionDescriptor::kSlot); 3626 StoreTransitionDescriptor::kSlot);
3662 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - 3627 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
3663 StoreWithVectorDescriptor::kVector == 3628 StoreWithVectorDescriptor::kVector ==
3664 StoreTransitionDescriptor::kParameterCount - 3629 StoreTransitionDescriptor::kParameterCount -
3665 StoreTransitionDescriptor::kVector); 3630 StoreTransitionDescriptor::kVector);
3666 __ jmp(Operand::StaticVariable(virtual_register)); 3631 __ jmp(feedback);
3667 3632
3668 __ bind(&prepare_next); 3633 __ bind(&prepare_next);
3669 __ add(counter, Immediate(Smi::FromInt(3))); 3634 __ add(counter, Immediate(Smi::FromInt(3)));
3670 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 3635 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
3671 __ j(less, &next_loop); 3636 __ j(less, &next_loop);
3672 3637
3673 // We exhausted our array of map handler pairs. 3638 // We exhausted our array of map handler pairs.
3674 __ bind(&pop_and_miss); 3639 __ bind(&pop_and_miss);
3675 __ pop(key); 3640 __ pop(key);
3676 __ pop(vector);
3677 __ pop(receiver); 3641 __ pop(receiver);
3678 __ jmp(miss); 3642 __ jmp(miss);
3679 3643
3680 __ bind(&load_smi_map); 3644 __ bind(&load_smi_map);
3681 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); 3645 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
3682 __ jmp(&compare_map); 3646 __ jmp(&compare_map);
3683 } 3647 }
3684 3648
3685 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 3649 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
3686 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx 3650 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx
(...skipping 15 matching lines...) Expand all
3702 // If the vector is not on the stack, then insert the vector beneath 3666 // If the vector is not on the stack, then insert the vector beneath
3703 // return address in order to prepare for calling handler with 3667 // return address in order to prepare for calling handler with
3704 // StoreWithVector calling convention. 3668 // StoreWithVector calling convention.
3705 __ push(Operand(esp, 0)); 3669 __ push(Operand(esp, 0));
3706 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); 3670 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
3707 __ RecordComment("]"); 3671 __ RecordComment("]");
3708 } else { 3672 } else {
3709 __ mov(vector, Operand(esp, 1 * kPointerSize)); 3673 __ mov(vector, Operand(esp, 1 * kPointerSize));
3710 } 3674 }
3711 __ mov(slot, Operand(esp, 2 * kPointerSize)); 3675 __ mov(slot, Operand(esp, 2 * kPointerSize));
3712 __ mov(value, Operand(esp, 3 * kPointerSize));
3713 } 3676 }
3714 3677
3715 __ push(value);
3716
3717 Register scratch = value; 3678 Register scratch = value;
3718 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 3679 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
3719 FixedArray::kHeaderSize)); 3680 FixedArray::kHeaderSize));
3720 3681
3721 // Is it a weak cell? 3682 // Is it a weak cell?
3722 Label try_array; 3683 Label try_array;
3723 Label not_array, smi_key, key_okay; 3684 Label not_array, smi_key, key_okay;
3724 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); 3685 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
3725 __ j(not_equal, &try_array); 3686 __ j(not_equal, &try_array);
3726 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); 3687 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
3727 3688
3728 // Is it a fixed array? 3689 // Is it a fixed array?
3729 __ bind(&try_array); 3690 __ bind(&try_array);
3730 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); 3691 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
3731 __ j(not_equal, &not_array); 3692 __ j(not_equal, &not_array);
3732 HandlePolymorphicKeyedStoreCase(masm, receiver, key, vector, slot, scratch, 3693 HandlePolymorphicKeyedStoreCase(masm, receiver, key, vector, slot, scratch,
3733 &miss); 3694 &miss);
3734 3695
3735 __ bind(&not_array); 3696 __ bind(&not_array);
3736 Label try_poly_name; 3697 Label try_poly_name;
3737 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); 3698 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
3738 __ j(not_equal, &try_poly_name); 3699 __ j(not_equal, &try_poly_name);
3739 3700
3740 __ pop(value);
3741
3742 Handle<Code> megamorphic_stub = 3701 Handle<Code> megamorphic_stub =
3743 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState()); 3702 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
3744 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); 3703 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
3745 3704
3746 __ bind(&try_poly_name); 3705 __ bind(&try_poly_name);
3747 // We might have a name in feedback, and a fixed array in the next slot. 3706 // We might have a name in feedback, and a fixed array in the next slot.
3748 __ cmp(key, scratch); 3707 __ cmp(key, scratch);
3749 __ j(not_equal, &miss); 3708 __ j(not_equal, &miss);
3750 // If the name comparison succeeded, we know we have a fixed array with 3709 // If the name comparison succeeded, we know we have a fixed array with
3751 // at least one map/handler pair. 3710 // at least one map/handler pair.
3752 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 3711 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
3753 FixedArray::kHeaderSize + kPointerSize)); 3712 FixedArray::kHeaderSize + kPointerSize));
3754 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false, 3713 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false,
3755 &miss); 3714 &miss);
3756 3715
3757 __ bind(&miss); 3716 __ bind(&miss);
3758 __ pop(value);
3759 KeyedStoreIC::GenerateMiss(masm); 3717 KeyedStoreIC::GenerateMiss(masm);
3760 } 3718 }
3761 3719
3762 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 3720 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
3763 __ EmitLoadTypeFeedbackVector(ebx); 3721 __ EmitLoadTypeFeedbackVector(ebx);
3764 CallICStub stub(isolate(), state()); 3722 CallICStub stub(isolate(), state());
3765 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 3723 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
3766 } 3724 }
3767 3725
3768 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 3726 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
(...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after
5303 kStackUnwindSpace, nullptr, return_value_operand, 5261 kStackUnwindSpace, nullptr, return_value_operand,
5304 NULL); 5262 NULL);
5305 } 5263 }
5306 5264
5307 #undef __ 5265 #undef __
5308 5266
5309 } // namespace internal 5267 } // namespace internal
5310 } // namespace v8 5268 } // namespace v8
5311 5269
5312 #endif // V8_TARGET_ARCH_X87 5270 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x87/macro-assembler-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698