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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 164316: Remove much of the register allocation overhead from ARM. When... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 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 | src/arm/virtual-frame-arm.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 } 1029 }
1030 __ orr(r2, r0, Operand(r1)); 1030 __ orr(r2, r0, Operand(r1));
1031 __ tst(r2, Operand(kSmiTagMask)); 1031 __ tst(r2, Operand(kSmiTagMask));
1032 smi.Branch(eq); 1032 smi.Branch(eq);
1033 1033
1034 // Perform non-smi comparison by stub. 1034 // Perform non-smi comparison by stub.
1035 // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0. 1035 // CompareStub takes arguments in r0 and r1, returns <0, >0 or 0 in r0.
1036 // We call with 0 args because there are 0 on the stack. 1036 // We call with 0 args because there are 0 on the stack.
1037 CompareStub stub(cc, strict); 1037 CompareStub stub(cc, strict);
1038 frame_->CallStub(&stub, 0); 1038 frame_->CallStub(&stub, 0);
1039 1039 __ cmp(r0, Operand(0));
1040 Result result = allocator_->Allocate(r0);
1041 ASSERT(result.is_valid());
1042 __ cmp(result.reg(), Operand(0));
1043 result.Unuse();
1044 exit.Jump(); 1040 exit.Jump();
1045 1041
1046 // Do smi comparisons by pointer comparison. 1042 // Do smi comparisons by pointer comparison.
1047 smi.Bind(); 1043 smi.Bind();
1048 __ cmp(r1, Operand(r0)); 1044 __ cmp(r1, Operand(r0));
1049 1045
1050 exit.Bind(); 1046 exit.Bind();
1051 cc_reg_ = cc; 1047 cc_reg_ = cc;
1052 } 1048 }
1053 1049
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 // [Object] 1738 // [Object]
1743 1739
1744 // Check if enumerable is already a JSObject 1740 // Check if enumerable is already a JSObject
1745 __ tst(r0, Operand(kSmiTagMask)); 1741 __ tst(r0, Operand(kSmiTagMask));
1746 primitive.Branch(eq); 1742 primitive.Branch(eq);
1747 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 1743 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
1748 jsobject.Branch(hs); 1744 jsobject.Branch(hs);
1749 1745
1750 primitive.Bind(); 1746 primitive.Bind();
1751 frame_->EmitPush(r0); 1747 frame_->EmitPush(r0);
1752 Result arg_count = allocator_->Allocate(r0); 1748 Result arg_count(r0);
1753 ASSERT(arg_count.is_valid()); 1749 __ mov(r0, Operand(0));
1754 __ mov(arg_count.reg(), Operand(0));
1755 frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1); 1750 frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1);
1756 1751
1757 jsobject.Bind(); 1752 jsobject.Bind();
1758 // Get the set of properties (as a FixedArray or Map). 1753 // Get the set of properties (as a FixedArray or Map).
1759 frame_->EmitPush(r0); // duplicate the object being enumerated 1754 frame_->EmitPush(r0); // duplicate the object being enumerated
1760 frame_->EmitPush(r0); 1755 frame_->EmitPush(r0);
1761 frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1756 frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1);
1762 1757
1763 // If we got a Map, we can do a fast modification check. 1758 // If we got a Map, we can do a fast modification check.
1764 // Otherwise, we got a FixedArray, and we have to do a slow check. 1759 // Otherwise, we got a FixedArray, and we have to do a slow check.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 // If not, we have to filter the key. 1820 // If not, we have to filter the key.
1826 __ ldr(r1, frame_->ElementAt(4)); 1821 __ ldr(r1, frame_->ElementAt(4));
1827 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); 1822 __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset));
1828 __ cmp(r1, Operand(r2)); 1823 __ cmp(r1, Operand(r2));
1829 end_del_check.Branch(eq); 1824 end_del_check.Branch(eq);
1830 1825
1831 // Convert the entry to a string (or null if it isn't a property anymore). 1826 // Convert the entry to a string (or null if it isn't a property anymore).
1832 __ ldr(r0, frame_->ElementAt(4)); // push enumerable 1827 __ ldr(r0, frame_->ElementAt(4)); // push enumerable
1833 frame_->EmitPush(r0); 1828 frame_->EmitPush(r0);
1834 frame_->EmitPush(r3); // push entry 1829 frame_->EmitPush(r3); // push entry
1835 Result arg_count_register = allocator_->Allocate(r0); 1830 Result arg_count_reg(r0);
1836 ASSERT(arg_count_register.is_valid()); 1831 __ mov(r0, Operand(1));
1837 __ mov(arg_count_register.reg(), Operand(1)); 1832 frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS, &arg_count_reg, 2);
1838 Result result = frame_->InvokeBuiltin(Builtins::FILTER_KEY, 1833 __ mov(r3, Operand(r0));
1839 CALL_JS,
1840 &arg_count_register,
1841 2);
1842 __ mov(r3, Operand(result.reg()));
1843 result.Unuse();
1844 1834
1845 // If the property has been removed while iterating, we just skip it. 1835 // If the property has been removed while iterating, we just skip it.
1846 __ cmp(r3, Operand(Factory::null_value())); 1836 __ cmp(r3, Operand(Factory::null_value()));
1847 node->continue_target()->Branch(eq); 1837 node->continue_target()->Branch(eq);
1848 1838
1849 end_del_check.Bind(); 1839 end_del_check.Bind();
1850 // Store the entry in the 'each' expression and take another spin in the 1840 // Store the entry in the 'each' expression and take another spin in the
1851 // loop. r3: i'th entry of the enum cache (or string there of) 1841 // loop. r3: i'th entry of the enum cache (or string there of)
1852 frame_->EmitPush(r3); // push entry 1842 frame_->EmitPush(r3); // push entry
1853 { Reference each(this, node->each()); 1843 { Reference each(this, node->each());
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 __ b(&next); 2416 __ b(&next);
2427 __ bind(&fast); 2417 __ bind(&fast);
2428 } 2418 }
2429 2419
2430 // All extension objects were empty and it is safe to use a global 2420 // All extension objects were empty and it is safe to use a global
2431 // load IC call. 2421 // load IC call.
2432 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 2422 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
2433 // Load the global object. 2423 // Load the global object.
2434 LoadGlobal(); 2424 LoadGlobal();
2435 // Setup the name register. 2425 // Setup the name register.
2436 Result name = allocator_->Allocate(r2); 2426 Result name(r2);
2437 ASSERT(name.is_valid()); // We are in spilled code. 2427 __ mov(r2, Operand(slot->var()->name()));
2438 __ mov(name.reg(), Operand(slot->var()->name()));
2439 // Call IC stub. 2428 // Call IC stub.
2440 if (typeof_state == INSIDE_TYPEOF) { 2429 if (typeof_state == INSIDE_TYPEOF) {
2441 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, &name, 0); 2430 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, &name, 0);
2442 } else { 2431 } else {
2443 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, &name, 0); 2432 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, &name, 0);
2444 } 2433 }
2445 2434
2446 // Drop the global object. The result is in r0. 2435 // Drop the global object. The result is in r0.
2447 frame_->Drop(); 2436 frame_->Drop();
2448 } 2437 }
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
2768 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 2757 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
2769 #ifdef DEBUG 2758 #ifdef DEBUG
2770 int original_height = frame_->height(); 2759 int original_height = frame_->height();
2771 #endif 2760 #endif
2772 VirtualFrame::SpilledScope spilled_scope; 2761 VirtualFrame::SpilledScope spilled_scope;
2773 // Call runtime routine to allocate the catch extension object and 2762 // Call runtime routine to allocate the catch extension object and
2774 // assign the exception value to the catch variable. 2763 // assign the exception value to the catch variable.
2775 Comment cmnt(masm_, "[ CatchExtensionObject"); 2764 Comment cmnt(masm_, "[ CatchExtensionObject");
2776 LoadAndSpill(node->key()); 2765 LoadAndSpill(node->key());
2777 LoadAndSpill(node->value()); 2766 LoadAndSpill(node->value());
2778 Result result = 2767 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
2779 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 2768 frame_->EmitPush(r0);
2780 frame_->EmitPush(result.reg());
2781 ASSERT(frame_->height() == original_height + 1); 2769 ASSERT(frame_->height() == original_height + 1);
2782 } 2770 }
2783 2771
2784 2772
2785 void CodeGenerator::VisitAssignment(Assignment* node) { 2773 void CodeGenerator::VisitAssignment(Assignment* node) {
2786 #ifdef DEBUG 2774 #ifdef DEBUG
2787 int original_height = frame_->height(); 2775 int original_height = frame_->height();
2788 #endif 2776 #endif
2789 VirtualFrame::SpilledScope spilled_scope; 2777 VirtualFrame::SpilledScope spilled_scope;
2790 Comment cmnt(masm_, "[ Assignment"); 2778 Comment cmnt(masm_, "[ Assignment");
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 LoadGlobal(); 3098 LoadGlobal();
3111 3099
3112 // Push the arguments ("left-to-right") on the stack. 3100 // Push the arguments ("left-to-right") on the stack.
3113 ZoneList<Expression*>* args = node->arguments(); 3101 ZoneList<Expression*>* args = node->arguments();
3114 int arg_count = args->length(); 3102 int arg_count = args->length();
3115 for (int i = 0; i < arg_count; i++) { 3103 for (int i = 0; i < arg_count; i++) {
3116 LoadAndSpill(args->at(i)); 3104 LoadAndSpill(args->at(i));
3117 } 3105 }
3118 3106
3119 // r0: the number of arguments. 3107 // r0: the number of arguments.
3120 Result num_args = allocator_->Allocate(r0); 3108 Result num_args(r0);
3121 ASSERT(num_args.is_valid()); 3109 __ mov(r0, Operand(arg_count));
3122 __ mov(num_args.reg(), Operand(arg_count));
3123 3110
3124 // Load the function into r1 as per calling convention. 3111 // Load the function into r1 as per calling convention.
3125 Result function = allocator_->Allocate(r1); 3112 Result function(r1);
3126 ASSERT(function.is_valid()); 3113 __ ldr(r1, frame_->ElementAt(arg_count + 1));
3127 __ ldr(function.reg(), frame_->ElementAt(arg_count + 1));
3128 3114
3129 // Call the construct call builtin that handles allocation and 3115 // Call the construct call builtin that handles allocation and
3130 // constructor invocation. 3116 // constructor invocation.
3131 CodeForSourcePosition(node->position()); 3117 CodeForSourcePosition(node->position());
3132 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); 3118 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
3133 Result result = frame_->CallCodeObject(ic, 3119 frame_->CallCodeObject(ic,
3134 RelocInfo::CONSTRUCT_CALL, 3120 RelocInfo::CONSTRUCT_CALL,
3135 &num_args, 3121 &num_args,
3136 &function, 3122 &function,
3137 arg_count + 1); 3123 arg_count + 1);
3138 3124
3139 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). 3125 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
3140 __ str(r0, frame_->Top()); 3126 __ str(r0, frame_->Top());
3141 ASSERT(frame_->height() == original_height + 1); 3127 ASSERT(frame_->height() == original_height + 1);
3142 } 3128 }
3143 3129
3144 3130
3145 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { 3131 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
3146 VirtualFrame::SpilledScope spilled_scope; 3132 VirtualFrame::SpilledScope spilled_scope;
3147 ASSERT(args->length() == 1); 3133 ASSERT(args->length() == 1);
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
3470 // LoadCondition may (and usually does) leave a test and branch to 3456 // LoadCondition may (and usually does) leave a test and branch to
3471 // be emitted by the caller. In that case, negate the condition. 3457 // be emitted by the caller. In that case, negate the condition.
3472 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); 3458 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_);
3473 3459
3474 } else if (op == Token::DELETE) { 3460 } else if (op == Token::DELETE) {
3475 Property* property = node->expression()->AsProperty(); 3461 Property* property = node->expression()->AsProperty();
3476 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); 3462 Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
3477 if (property != NULL) { 3463 if (property != NULL) {
3478 LoadAndSpill(property->obj()); 3464 LoadAndSpill(property->obj());
3479 LoadAndSpill(property->key()); 3465 LoadAndSpill(property->key());
3480 Result arg_count = allocator_->Allocate(r0); 3466 Result arg_count(r0);
3481 ASSERT(arg_count.is_valid()); 3467 __ mov(r0, Operand(1)); // not counting receiver
3482 __ mov(arg_count.reg(), Operand(1)); // not counting receiver
3483 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2); 3468 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
3484 3469
3485 } else if (variable != NULL) { 3470 } else if (variable != NULL) {
3486 Slot* slot = variable->slot(); 3471 Slot* slot = variable->slot();
3487 if (variable->is_global()) { 3472 if (variable->is_global()) {
3488 LoadGlobal(); 3473 LoadGlobal();
3489 __ mov(r0, Operand(variable->name())); 3474 __ mov(r0, Operand(variable->name()));
3490 frame_->EmitPush(r0); 3475 frame_->EmitPush(r0);
3491 Result arg_count = allocator_->Allocate(r0); 3476 Result arg_count(r0);
3492 ASSERT(arg_count.is_valid()); 3477 __ mov(r0, Operand(1)); // not counting receiver
3493 __ mov(arg_count.reg(), Operand(1)); // not counting receiver
3494 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2); 3478 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
3495 3479
3496 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 3480 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
3497 // lookup the context holding the named variable 3481 // lookup the context holding the named variable
3498 frame_->EmitPush(cp); 3482 frame_->EmitPush(cp);
3499 __ mov(r0, Operand(variable->name())); 3483 __ mov(r0, Operand(variable->name()));
3500 frame_->EmitPush(r0); 3484 frame_->EmitPush(r0);
3501 frame_->CallRuntime(Runtime::kLookupContext, 2); 3485 frame_->CallRuntime(Runtime::kLookupContext, 2);
3502 // r0: context 3486 // r0: context
3503 frame_->EmitPush(r0); 3487 frame_->EmitPush(r0);
3504 __ mov(r0, Operand(variable->name())); 3488 __ mov(r0, Operand(variable->name()));
3505 frame_->EmitPush(r0); 3489 frame_->EmitPush(r0);
3506 Result arg_count = allocator_->Allocate(r0); 3490 Result arg_count(r0);
3507 ASSERT(arg_count.is_valid()); 3491 __ mov(r0, Operand(1)); // not counting receiver
3508 __ mov(arg_count.reg(), Operand(1)); // not counting receiver
3509 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2); 3492 frame_->InvokeBuiltin(Builtins::DELETE, CALL_JS, &arg_count, 2);
3510 3493
3511 } else { 3494 } else {
3512 // Default: Result of deleting non-global, not dynamically 3495 // Default: Result of deleting non-global, not dynamically
3513 // introduced variables is false. 3496 // introduced variables is false.
3514 __ mov(r0, Operand(Factory::false_value())); 3497 __ mov(r0, Operand(Factory::false_value()));
3515 } 3498 }
3516 3499
3517 } else { 3500 } else {
3518 // Default: Result of deleting expressions is true. 3501 // Default: Result of deleting expressions is true.
(...skipping 30 matching lines...) Expand all
3549 } 3532 }
3550 3533
3551 case Token::BIT_NOT: { 3534 case Token::BIT_NOT: {
3552 // smi check 3535 // smi check
3553 JumpTarget smi_label; 3536 JumpTarget smi_label;
3554 JumpTarget continue_label; 3537 JumpTarget continue_label;
3555 __ tst(r0, Operand(kSmiTagMask)); 3538 __ tst(r0, Operand(kSmiTagMask));
3556 smi_label.Branch(eq); 3539 smi_label.Branch(eq);
3557 3540
3558 frame_->EmitPush(r0); 3541 frame_->EmitPush(r0);
3559 Result arg_count = allocator_->Allocate(r0); 3542 Result arg_count(r0);
3560 ASSERT(arg_count.is_valid()); 3543 __ mov(r0, Operand(0)); // not counting receiver
3561 __ mov(arg_count.reg(), Operand(0)); // not counting receiver
3562 frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1); 3544 frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1);
3563 3545
3564 continue_label.Jump(); 3546 continue_label.Jump();
3565 smi_label.Bind(); 3547 smi_label.Bind();
3566 __ mvn(r0, Operand(r0)); 3548 __ mvn(r0, Operand(r0));
3567 __ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag 3549 __ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag
3568 continue_label.Bind(); 3550 continue_label.Bind();
3569 break; 3551 break;
3570 } 3552 }
3571 3553
3572 case Token::VOID: 3554 case Token::VOID:
3573 // since the stack top is cached in r0, popping and then 3555 // since the stack top is cached in r0, popping and then
3574 // pushing a value can be done by just writing to r0. 3556 // pushing a value can be done by just writing to r0.
3575 __ mov(r0, Operand(Factory::undefined_value())); 3557 __ mov(r0, Operand(Factory::undefined_value()));
3576 break; 3558 break;
3577 3559
3578 case Token::ADD: { 3560 case Token::ADD: {
3579 // Smi check. 3561 // Smi check.
3580 JumpTarget continue_label; 3562 JumpTarget continue_label;
3581 __ tst(r0, Operand(kSmiTagMask)); 3563 __ tst(r0, Operand(kSmiTagMask));
3582 continue_label.Branch(eq); 3564 continue_label.Branch(eq);
3583 frame_->EmitPush(r0); 3565 frame_->EmitPush(r0);
3584 Result arg_count = allocator_->Allocate(r0); 3566 Result arg_count(r0);
3585 ASSERT(arg_count.is_valid()); 3567 __ mov(r0, Operand(0)); // not counting receiver
3586 __ mov(arg_count.reg(), Operand(0)); // not counting receiver
3587 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); 3568 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
3588 continue_label.Bind(); 3569 continue_label.Bind();
3589 break; 3570 break;
3590 } 3571 }
3591 default: 3572 default:
3592 UNREACHABLE(); 3573 UNREACHABLE();
3593 } 3574 }
3594 frame_->EmitPush(r0); // r0 has result 3575 frame_->EmitPush(r0); // r0 has result
3595 } 3576 }
3596 ASSERT(!has_valid_frame() || 3577 ASSERT(!has_valid_frame() ||
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3662 __ sub(r0, r0, Operand(r1)); 3643 __ sub(r0, r0, Operand(r1));
3663 } else { 3644 } else {
3664 __ add(r0, r0, Operand(r1)); 3645 __ add(r0, r0, Operand(r1));
3665 } 3646 }
3666 3647
3667 // Slow case: Convert to number. 3648 // Slow case: Convert to number.
3668 slow.Bind(); 3649 slow.Bind();
3669 { 3650 {
3670 // Convert the operand to a number. 3651 // Convert the operand to a number.
3671 frame_->EmitPush(r0); 3652 frame_->EmitPush(r0);
3672 Result arg_count = allocator_->Allocate(r0); 3653 Result arg_count(r0);
3673 ASSERT(arg_count.is_valid()); 3654 __ mov(r0, Operand(0));
3674 __ mov(arg_count.reg(), Operand(0));
3675 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); 3655 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
3676 } 3656 }
3677 if (is_postfix) { 3657 if (is_postfix) {
3678 // Postfix: store to result (on the stack). 3658 // Postfix: store to result (on the stack).
3679 __ str(r0, frame_->ElementAt(target.size())); 3659 __ str(r0, frame_->ElementAt(target.size()));
3680 } 3660 }
3681 3661
3682 // Compute the new value. 3662 // Compute the new value.
3683 __ mov(r1, Operand(Smi::FromInt(1))); 3663 __ mov(r1, Operand(Smi::FromInt(1)));
3684 frame_->EmitPush(r0); 3664 frame_->EmitPush(r0);
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
4041 Comparison(ge, left, right); 4021 Comparison(ge, left, right);
4042 break; 4022 break;
4043 4023
4044 case Token::EQ_STRICT: 4024 case Token::EQ_STRICT:
4045 Comparison(eq, left, right, true); 4025 Comparison(eq, left, right, true);
4046 break; 4026 break;
4047 4027
4048 case Token::IN: { 4028 case Token::IN: {
4049 LoadAndSpill(left); 4029 LoadAndSpill(left);
4050 LoadAndSpill(right); 4030 LoadAndSpill(right);
4051 Result arg_count = allocator_->Allocate(r0); 4031 Result arg_count(r0);
4052 ASSERT(arg_count.is_valid()); 4032 __ mov(r0, Operand(1)); // not counting receiver
4053 __ mov(arg_count.reg(), Operand(1)); // not counting receiver 4033 frame_->InvokeBuiltin(Builtins::IN, CALL_JS, &arg_count, 2);
4054 Result result = frame_->InvokeBuiltin(Builtins::IN, 4034 frame_->EmitPush(r0);
4055 CALL_JS,
4056 &arg_count,
4057 2);
4058 frame_->EmitPush(result.reg());
4059 break; 4035 break;
4060 } 4036 }
4061 4037
4062 case Token::INSTANCEOF: { 4038 case Token::INSTANCEOF: {
4063 LoadAndSpill(left); 4039 LoadAndSpill(left);
4064 LoadAndSpill(right); 4040 LoadAndSpill(right);
4065 InstanceofStub stub; 4041 InstanceofStub stub;
4066 Result result = frame_->CallStub(&stub, 2); 4042 frame_->CallStub(&stub, 2);
4067 // At this point if instanceof succeeded then r0 == 0. 4043 // At this point if instanceof succeeded then r0 == 0.
4068 __ tst(result.reg(), Operand(result.reg())); 4044 __ tst(r0, Operand(r0));
4069 cc_reg_ = eq; 4045 cc_reg_ = eq;
4070 break; 4046 break;
4071 } 4047 }
4072 4048
4073 default: 4049 default:
4074 UNREACHABLE(); 4050 UNREACHABLE();
4075 } 4051 }
4076 ASSERT((has_cc() && frame_->height() == original_height) || 4052 ASSERT((has_cc() && frame_->height() == original_height) ||
4077 (!has_cc() && frame_->height() == original_height + 1)); 4053 (!has_cc() && frame_->height() == original_height + 1));
4078 } 4054 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4128 // distinction between expressions in a typeof and not in a typeof. If 4104 // distinction between expressions in a typeof and not in a typeof. If
4129 // there is a chance that reference errors can be thrown below, we 4105 // there is a chance that reference errors can be thrown below, we
4130 // must distinguish between the two kinds of loads (typeof expression 4106 // must distinguish between the two kinds of loads (typeof expression
4131 // loads must not throw a reference error). 4107 // loads must not throw a reference error).
4132 VirtualFrame* frame = cgen_->frame(); 4108 VirtualFrame* frame = cgen_->frame();
4133 Comment cmnt(masm, "[ Load from named Property"); 4109 Comment cmnt(masm, "[ Load from named Property");
4134 Handle<String> name(GetName()); 4110 Handle<String> name(GetName());
4135 Variable* var = expression_->AsVariableProxy()->AsVariable(); 4111 Variable* var = expression_->AsVariableProxy()->AsVariable();
4136 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 4112 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
4137 // Setup the name register. 4113 // Setup the name register.
4138 Result name_reg = cgen_->allocator()->Allocate(r2); 4114 Result name_reg(r2);
4139 ASSERT(name_reg.is_valid()); 4115 __ mov(r2, Operand(name));
4140 __ mov(name_reg.reg(), Operand(name));
4141 ASSERT(var == NULL || var->is_global()); 4116 ASSERT(var == NULL || var->is_global());
4142 RelocInfo::Mode rmode = (var == NULL) 4117 RelocInfo::Mode rmode = (var == NULL)
4143 ? RelocInfo::CODE_TARGET 4118 ? RelocInfo::CODE_TARGET
4144 : RelocInfo::CODE_TARGET_CONTEXT; 4119 : RelocInfo::CODE_TARGET_CONTEXT;
4145 Result answer = frame->CallCodeObject(ic, rmode, &name_reg, 0); 4120 frame->CallCodeObject(ic, rmode, &name_reg, 0);
4146 frame->EmitPush(answer.reg()); 4121 frame->EmitPush(r0);
4147 break; 4122 break;
4148 } 4123 }
4149 4124
4150 case KEYED: { 4125 case KEYED: {
4151 // TODO(1241834): Make sure that this it is safe to ignore the 4126 // TODO(1241834): Make sure that this it is safe to ignore the
4152 // distinction between expressions in a typeof and not in a typeof. 4127 // distinction between expressions in a typeof and not in a typeof.
4153 4128
4154 // TODO(181): Implement inlined version of array indexing once 4129 // TODO(181): Implement inlined version of array indexing once
4155 // loop nesting is properly tracked on ARM. 4130 // loop nesting is properly tracked on ARM.
4156 VirtualFrame* frame = cgen_->frame(); 4131 VirtualFrame* frame = cgen_->frame();
4157 Comment cmnt(masm, "[ Load from keyed Property"); 4132 Comment cmnt(masm, "[ Load from keyed Property");
4158 ASSERT(property != NULL); 4133 ASSERT(property != NULL);
4159 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 4134 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
4160 Variable* var = expression_->AsVariableProxy()->AsVariable(); 4135 Variable* var = expression_->AsVariableProxy()->AsVariable();
4161 ASSERT(var == NULL || var->is_global()); 4136 ASSERT(var == NULL || var->is_global());
4162 RelocInfo::Mode rmode = (var == NULL) 4137 RelocInfo::Mode rmode = (var == NULL)
4163 ? RelocInfo::CODE_TARGET 4138 ? RelocInfo::CODE_TARGET
4164 : RelocInfo::CODE_TARGET_CONTEXT; 4139 : RelocInfo::CODE_TARGET_CONTEXT;
4165 Result answer = frame->CallCodeObject(ic, rmode, 0); 4140 frame->CallCodeObject(ic, rmode, 0);
4166 frame->EmitPush(answer.reg()); 4141 frame->EmitPush(r0);
4167 break; 4142 break;
4168 } 4143 }
4169 4144
4170 default: 4145 default:
4171 UNREACHABLE(); 4146 UNREACHABLE();
4172 } 4147 }
4173 } 4148 }
4174 4149
4175 4150
4176 void Reference::SetValue(InitState init_state) { 4151 void Reference::SetValue(InitState init_state) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
4265 } 4240 }
4266 break; 4241 break;
4267 } 4242 }
4268 4243
4269 case NAMED: { 4244 case NAMED: {
4270 Comment cmnt(masm, "[ Store to named Property"); 4245 Comment cmnt(masm, "[ Store to named Property");
4271 // Call the appropriate IC code. 4246 // Call the appropriate IC code.
4272 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 4247 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
4273 Handle<String> name(GetName()); 4248 Handle<String> name(GetName());
4274 4249
4275 Result value = cgen_->allocator()->Allocate(r0); 4250 Result value(r0);
4276 ASSERT(value.is_valid()); 4251 frame->EmitPop(r0);
4277 frame->EmitPop(value.reg());
4278 4252
4279 // Setup the name register. 4253 // Setup the name register.
4280 Result property_name = cgen_->allocator()->Allocate(r2); 4254 Result property_name(r2);
4281 ASSERT(property_name.is_valid()); 4255 __ mov(r2, Operand(name));
4282 __ mov(property_name.reg(), Operand(name)); 4256 frame->CallCodeObject(ic,
4283 Result answer = frame->CallCodeObject(ic, 4257 RelocInfo::CODE_TARGET,
4284 RelocInfo::CODE_TARGET, 4258 &value,
4285 &value, 4259 &property_name,
4286 &property_name, 4260 0);
4287 0); 4261 frame->EmitPush(r0);
4288 frame->EmitPush(answer.reg());
4289 break; 4262 break;
4290 } 4263 }
4291 4264
4292 case KEYED: { 4265 case KEYED: {
4293 Comment cmnt(masm, "[ Store to keyed Property"); 4266 Comment cmnt(masm, "[ Store to keyed Property");
4294 Property* property = expression_->AsProperty(); 4267 Property* property = expression_->AsProperty();
4295 ASSERT(property != NULL); 4268 ASSERT(property != NULL);
4296 cgen_->CodeForSourcePosition(property->position()); 4269 cgen_->CodeForSourcePosition(property->position());
4297 4270
4298 // Call IC code. 4271 // Call IC code.
4299 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 4272 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
4300 // TODO(1222589): Make the IC grab the values from the stack. 4273 // TODO(1222589): Make the IC grab the values from the stack.
4301 Result value = cgen_->allocator()->Allocate(r0); 4274 Result value(r0);
4302 ASSERT(value.is_valid()); 4275 frame->EmitPop(r0); // value
4303 frame->EmitPop(value.reg()); // value 4276 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0);
4304 Result result = 4277 frame->EmitPush(r0);
4305 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, &value, 0);
4306 frame->EmitPush(result.reg());
4307 break; 4278 break;
4308 } 4279 }
4309 4280
4310 default: 4281 default:
4311 UNREACHABLE(); 4282 UNREACHABLE();
4312 } 4283 }
4313 } 4284 }
4314 4285
4315 4286
4316 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz 4287 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz
(...skipping 1945 matching lines...) Expand 10 before | Expand all | Expand 10 after
6262 int CompareStub::MinorKey() { 6233 int CompareStub::MinorKey() {
6263 // Encode the two parameters in a unique 16 bit value. 6234 // Encode the two parameters in a unique 16 bit value.
6264 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); 6235 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15));
6265 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); 6236 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0);
6266 } 6237 }
6267 6238
6268 6239
6269 #undef __ 6240 #undef __
6270 6241
6271 } } // namespace v8::internal 6242 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/virtual-frame-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698