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

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 3388004: Add support for near labels.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 // Visit all the explicit declarations unless there is an illegal 155 // Visit all the explicit declarations unless there is an illegal
156 // redeclaration. 156 // redeclaration.
157 if (scope()->HasIllegalRedeclaration()) { 157 if (scope()->HasIllegalRedeclaration()) {
158 scope()->VisitIllegalRedeclaration(this); 158 scope()->VisitIllegalRedeclaration(this);
159 } else { 159 } else {
160 VisitDeclarations(scope()->declarations()); 160 VisitDeclarations(scope()->declarations());
161 } 161 }
162 } 162 }
163 163
164 { Comment cmnt(masm_, "[ Stack check"); 164 { Comment cmnt(masm_, "[ Stack check");
165 Label ok; 165 NearLabel ok;
166 ExternalReference stack_limit = 166 ExternalReference stack_limit =
167 ExternalReference::address_of_stack_limit(); 167 ExternalReference::address_of_stack_limit();
168 __ cmp(esp, Operand::StaticVariable(stack_limit)); 168 __ cmp(esp, Operand::StaticVariable(stack_limit));
169 __ j(above_equal, &ok, taken); 169 __ j(above_equal, &ok, taken);
170 StackCheckStub stub; 170 StackCheckStub stub;
171 __ CallStub(&stub); 171 __ CallStub(&stub);
172 __ bind(&ok); 172 __ bind(&ok);
173 } 173 }
174 174
175 if (FLAG_trace) { 175 if (FLAG_trace) {
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 Label* materialize_false) { 396 Label* materialize_false) {
397 switch (context) { 397 switch (context) {
398 case Expression::kUninitialized: 398 case Expression::kUninitialized:
399 399
400 case Expression::kEffect: 400 case Expression::kEffect:
401 ASSERT_EQ(materialize_true, materialize_false); 401 ASSERT_EQ(materialize_true, materialize_false);
402 __ bind(materialize_true); 402 __ bind(materialize_true);
403 break; 403 break;
404 404
405 case Expression::kValue: { 405 case Expression::kValue: {
406 Label done; 406 NearLabel done;
407 switch (location_) { 407 switch (location_) {
408 case kAccumulator: 408 case kAccumulator:
409 __ bind(materialize_true); 409 __ bind(materialize_true);
410 __ mov(result_register(), Factory::true_value()); 410 __ mov(result_register(), Factory::true_value());
411 __ jmp(&done); 411 __ jmp(&done);
412 __ bind(materialize_false); 412 __ bind(materialize_false);
413 __ mov(result_register(), Factory::false_value()); 413 __ mov(result_register(), Factory::false_value());
414 break; 414 break;
415 case kStack: 415 case kStack:
416 __ bind(materialize_true); 416 __ bind(materialize_true);
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 Comment cmnt(masm_, "[ Case comparison"); 678 Comment cmnt(masm_, "[ Case comparison");
679 __ bind(&next_test); 679 __ bind(&next_test);
680 next_test.Unuse(); 680 next_test.Unuse();
681 681
682 // Compile the label expression. 682 // Compile the label expression.
683 VisitForValue(clause->label(), kAccumulator); 683 VisitForValue(clause->label(), kAccumulator);
684 684
685 // Perform the comparison as if via '==='. 685 // Perform the comparison as if via '==='.
686 __ mov(edx, Operand(esp, 0)); // Switch value. 686 __ mov(edx, Operand(esp, 0)); // Switch value.
687 if (ShouldInlineSmiCase(Token::EQ_STRICT)) { 687 if (ShouldInlineSmiCase(Token::EQ_STRICT)) {
688 Label slow_case; 688 NearLabel slow_case;
689 __ mov(ecx, edx); 689 __ mov(ecx, edx);
690 __ or_(ecx, Operand(eax)); 690 __ or_(ecx, Operand(eax));
691 __ test(ecx, Immediate(kSmiTagMask)); 691 __ test(ecx, Immediate(kSmiTagMask));
692 __ j(not_zero, &slow_case, not_taken); 692 __ j(not_zero, &slow_case, not_taken);
693 __ cmp(edx, Operand(eax)); 693 __ cmp(edx, Operand(eax));
694 __ j(not_equal, &next_test); 694 __ j(not_equal, &next_test);
695 __ Drop(1); // Switch value is no longer needed. 695 __ Drop(1); // Switch value is no longer needed.
696 __ jmp(clause->body_target()->entry_label()); 696 __ jmp(clause->body_target()->entry_label());
697 __ bind(&slow_case); 697 __ bind(&slow_case);
698 } 698 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 // Get the object to enumerate over. Both SpiderMonkey and JSC 738 // Get the object to enumerate over. Both SpiderMonkey and JSC
739 // ignore null and undefined in contrast to the specification; see 739 // ignore null and undefined in contrast to the specification; see
740 // ECMA-262 section 12.6.4. 740 // ECMA-262 section 12.6.4.
741 VisitForValue(stmt->enumerable(), kAccumulator); 741 VisitForValue(stmt->enumerable(), kAccumulator);
742 __ cmp(eax, Factory::undefined_value()); 742 __ cmp(eax, Factory::undefined_value());
743 __ j(equal, &exit); 743 __ j(equal, &exit);
744 __ cmp(eax, Factory::null_value()); 744 __ cmp(eax, Factory::null_value());
745 __ j(equal, &exit); 745 __ j(equal, &exit);
746 746
747 // Convert the object to a JS object. 747 // Convert the object to a JS object.
748 Label convert, done_convert; 748 NearLabel convert, done_convert;
749 __ test(eax, Immediate(kSmiTagMask)); 749 __ test(eax, Immediate(kSmiTagMask));
750 __ j(zero, &convert); 750 __ j(zero, &convert);
751 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx); 751 __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
752 __ j(above_equal, &done_convert); 752 __ j(above_equal, &done_convert);
753 __ bind(&convert); 753 __ bind(&convert);
754 __ push(eax); 754 __ push(eax);
755 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 755 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
756 __ bind(&done_convert); 756 __ bind(&done_convert);
757 __ push(eax); 757 __ push(eax);
758 758
(...skipping 20 matching lines...) Expand all
779 __ j(equal, &call_runtime); 779 __ j(equal, &call_runtime);
780 780
781 // Check that there in an enum cache in the non-empty instance 781 // Check that there in an enum cache in the non-empty instance
782 // descriptors (edx). This is the case if the next enumeration 782 // descriptors (edx). This is the case if the next enumeration
783 // index field does not contain a smi. 783 // index field does not contain a smi.
784 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset)); 784 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
785 __ test(edx, Immediate(kSmiTagMask)); 785 __ test(edx, Immediate(kSmiTagMask));
786 __ j(zero, &call_runtime); 786 __ j(zero, &call_runtime);
787 787
788 // For all objects but the receiver, check that the cache is empty. 788 // For all objects but the receiver, check that the cache is empty.
789 Label check_prototype; 789 NearLabel check_prototype;
790 __ cmp(ecx, Operand(eax)); 790 __ cmp(ecx, Operand(eax));
791 __ j(equal, &check_prototype); 791 __ j(equal, &check_prototype);
792 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 792 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
793 __ cmp(edx, Factory::empty_fixed_array()); 793 __ cmp(edx, Factory::empty_fixed_array());
794 __ j(not_equal, &call_runtime); 794 __ j(not_equal, &call_runtime);
795 795
796 // Load the prototype from the map and loop if non-null. 796 // Load the prototype from the map and loop if non-null.
797 __ bind(&check_prototype); 797 __ bind(&check_prototype);
798 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 798 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
799 __ cmp(ecx, Factory::null_value()); 799 __ cmp(ecx, Factory::null_value());
800 __ j(not_equal, &next); 800 __ j(not_equal, &next);
801 801
802 // The enum cache is valid. Load the map of the object being 802 // The enum cache is valid. Load the map of the object being
803 // iterated over and use the cache for the iteration. 803 // iterated over and use the cache for the iteration.
804 Label use_cache; 804 NearLabel use_cache;
805 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 805 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
806 __ jmp(&use_cache); 806 __ jmp(&use_cache);
807 807
808 // Get the set of properties to enumerate. 808 // Get the set of properties to enumerate.
809 __ bind(&call_runtime); 809 __ bind(&call_runtime);
810 __ push(eax); // Duplicate the enumerable object on the stack. 810 __ push(eax); // Duplicate the enumerable object on the stack.
811 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 811 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
812 812
813 // If we got a map from the runtime call, we can do a fast 813 // If we got a map from the runtime call, we can do a fast
814 // modification check. Otherwise, we got a fixed array, and we have 814 // modification check. Otherwise, we got a fixed array, and we have
815 // to do a slow check. 815 // to do a slow check.
816 Label fixed_array; 816 NearLabel fixed_array;
817 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), Factory::meta_map()); 817 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), Factory::meta_map());
818 __ j(not_equal, &fixed_array); 818 __ j(not_equal, &fixed_array);
819 819
820 // We got a map in register eax. Get the enumeration cache from it. 820 // We got a map in register eax. Get the enumeration cache from it.
821 __ bind(&use_cache); 821 __ bind(&use_cache);
822 __ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset)); 822 __ mov(ecx, FieldOperand(eax, Map::kInstanceDescriptorsOffset));
823 __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset)); 823 __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
824 __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 824 __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
825 825
826 // Setup the four remaining stack slots. 826 // Setup the four remaining stack slots.
(...skipping 21 matching lines...) Expand all
848 // Get the current entry of the array into register ebx. 848 // Get the current entry of the array into register ebx.
849 __ mov(ebx, Operand(esp, 2 * kPointerSize)); 849 __ mov(ebx, Operand(esp, 2 * kPointerSize));
850 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); 850 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize));
851 851
852 // Get the expected map from the stack or a zero map in the 852 // Get the expected map from the stack or a zero map in the
853 // permanent slow case into register edx. 853 // permanent slow case into register edx.
854 __ mov(edx, Operand(esp, 3 * kPointerSize)); 854 __ mov(edx, Operand(esp, 3 * kPointerSize));
855 855
856 // Check if the expected map still matches that of the enumerable. 856 // Check if the expected map still matches that of the enumerable.
857 // If not, we have to filter the key. 857 // If not, we have to filter the key.
858 Label update_each; 858 NearLabel update_each;
859 __ mov(ecx, Operand(esp, 4 * kPointerSize)); 859 __ mov(ecx, Operand(esp, 4 * kPointerSize));
860 __ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset)); 860 __ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset));
861 __ j(equal, &update_each); 861 __ j(equal, &update_each);
862 862
863 // Convert the entry to a string or null if it isn't a property 863 // Convert the entry to a string or null if it isn't a property
864 // anymore. If the property has been removed while iterating, we 864 // anymore. If the property has been removed while iterating, we
865 // just skip it. 865 // just skip it.
866 __ push(ecx); // Enumerable. 866 __ push(ecx); // Enumerable.
867 __ push(ebx); // Current entry. 867 __ push(ebx); // Current entry.
868 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 868 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
869 __ test(eax, Operand(eax)); 869 __ test(eax, Operand(eax));
870 __ j(equal, loop_statement.continue_target()); 870 __ j(equal, loop_statement.continue_target());
871 __ mov(ebx, Operand(eax)); 871 __ mov(ebx, Operand(eax));
872 872
873 // Update the 'each' property or variable from the possibly filtered 873 // Update the 'each' property or variable from the possibly filtered
874 // entry in register ebx. 874 // entry in register ebx.
875 __ bind(&update_each); 875 __ bind(&update_each);
876 __ mov(result_register(), ebx); 876 __ mov(result_register(), ebx);
877 // Perform the assignment as if via '='. 877 // Perform the assignment as if via '='.
878 EmitAssignment(stmt->each()); 878 EmitAssignment(stmt->each());
879 879
880 // Generate code for the body of the loop. 880 // Generate code for the body of the loop.
881 Label stack_limit_hit, stack_check_done; 881 Label stack_limit_hit;
882 NearLabel stack_check_done;
882 Visit(stmt->body()); 883 Visit(stmt->body());
883 884
884 __ StackLimitCheck(&stack_limit_hit); 885 __ StackLimitCheck(&stack_limit_hit);
885 __ bind(&stack_check_done); 886 __ bind(&stack_check_done);
886 887
887 // Generate code for going to the next element by incrementing the 888 // Generate code for going to the next element by incrementing the
888 // index (smi) stored on top of the stack. 889 // index (smi) stored on top of the stack.
889 __ bind(loop_statement.continue_target()); 890 __ bind(loop_statement.continue_target());
890 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 891 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
891 __ jmp(&loop); 892 __ jmp(&loop);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 // If no outer scope calls eval, we do not need to check more 954 // If no outer scope calls eval, we do not need to check more
954 // context extensions. If we have reached an eval scope, we check 955 // context extensions. If we have reached an eval scope, we check
955 // all extensions from this point. 956 // all extensions from this point.
956 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; 957 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
957 s = s->outer_scope(); 958 s = s->outer_scope();
958 } 959 }
959 960
960 if (s != NULL && s->is_eval_scope()) { 961 if (s != NULL && s->is_eval_scope()) {
961 // Loop up the context chain. There is no frame effect so it is 962 // Loop up the context chain. There is no frame effect so it is
962 // safe to use raw labels here. 963 // safe to use raw labels here.
963 Label next, fast; 964 NearLabel next, fast;
964 if (!context.is(temp)) { 965 if (!context.is(temp)) {
965 __ mov(temp, context); 966 __ mov(temp, context);
966 } 967 }
967 __ bind(&next); 968 __ bind(&next);
968 // Terminate at global context. 969 // Terminate at global context.
969 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), 970 __ cmp(FieldOperand(temp, HeapObject::kMapOffset),
970 Immediate(Factory::global_context_map())); 971 Immediate(Factory::global_context_map()));
971 __ j(equal, &fast); 972 __ j(equal, &fast);
972 // Check that extension is NULL. 973 // Check that extension is NULL.
973 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 974 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 1113
1113 Apply(context, eax); 1114 Apply(context, eax);
1114 1115
1115 } else if (slot != NULL) { 1116 } else if (slot != NULL) {
1116 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1117 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1117 ? "Context slot" 1118 ? "Context slot"
1118 : "Stack slot"); 1119 : "Stack slot");
1119 if (var->mode() == Variable::CONST) { 1120 if (var->mode() == Variable::CONST) {
1120 // Constants may be the hole value if they have not been initialized. 1121 // Constants may be the hole value if they have not been initialized.
1121 // Unhole them. 1122 // Unhole them.
1122 Label done; 1123 NearLabel done;
1123 MemOperand slot_operand = EmitSlotSearch(slot, eax); 1124 MemOperand slot_operand = EmitSlotSearch(slot, eax);
1124 __ mov(eax, slot_operand); 1125 __ mov(eax, slot_operand);
1125 __ cmp(eax, Factory::the_hole_value()); 1126 __ cmp(eax, Factory::the_hole_value());
1126 __ j(not_equal, &done); 1127 __ j(not_equal, &done);
1127 __ mov(eax, Factory::undefined_value()); 1128 __ mov(eax, Factory::undefined_value());
1128 __ bind(&done); 1129 __ bind(&done);
1129 Apply(context, eax); 1130 Apply(context, eax);
1130 } else { 1131 } else {
1131 Apply(context, slot); 1132 Apply(context, slot);
1132 } 1133 }
(...skipping 28 matching lines...) Expand all
1161 // call. It is treated specially by the LoadIC code. 1162 // call. It is treated specially by the LoadIC code.
1162 __ nop(); 1163 __ nop();
1163 // Drop key and object left on the stack by IC. 1164 // Drop key and object left on the stack by IC.
1164 Apply(context, eax); 1165 Apply(context, eax);
1165 } 1166 }
1166 } 1167 }
1167 1168
1168 1169
1169 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1170 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1170 Comment cmnt(masm_, "[ RegExpLiteral"); 1171 Comment cmnt(masm_, "[ RegExpLiteral");
1171 Label materialized; 1172 NearLabel materialized;
1172 // Registers will be used as follows: 1173 // Registers will be used as follows:
1173 // edi = JS function. 1174 // edi = JS function.
1174 // ecx = literals array. 1175 // ecx = literals array.
1175 // ebx = regexp literal. 1176 // ebx = regexp literal.
1176 // eax = regexp literal clone. 1177 // eax = regexp literal clone.
1177 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1178 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1178 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 1179 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset));
1179 int literal_offset = 1180 int literal_offset =
1180 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1181 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1181 __ mov(ebx, FieldOperand(ecx, literal_offset)); 1182 __ mov(ebx, FieldOperand(ecx, literal_offset));
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 __ call(ic, RelocInfo::CODE_TARGET); 1483 __ call(ic, RelocInfo::CODE_TARGET);
1483 __ nop(); 1484 __ nop();
1484 } 1485 }
1485 1486
1486 1487
1487 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr, 1488 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
1488 Expression::Context context, 1489 Expression::Context context,
1489 OverwriteMode mode, 1490 OverwriteMode mode,
1490 bool left_is_constant_smi, 1491 bool left_is_constant_smi,
1491 Smi* value) { 1492 Smi* value) {
1492 Label call_stub, done; 1493 NearLabel call_stub;
1494 Label done;
1493 __ add(Operand(eax), Immediate(value)); 1495 __ add(Operand(eax), Immediate(value));
1494 __ j(overflow, &call_stub); 1496 __ j(overflow, &call_stub);
1495 __ test(eax, Immediate(kSmiTagMask)); 1497 __ test(eax, Immediate(kSmiTagMask));
1496 __ j(zero, &done); 1498 __ j(zero, &done);
1497 1499
1498 // Undo the optimistic add operation and call the shared stub. 1500 // Undo the optimistic add operation and call the shared stub.
1499 __ bind(&call_stub); 1501 __ bind(&call_stub);
1500 __ sub(Operand(eax), Immediate(value)); 1502 __ sub(Operand(eax), Immediate(value));
1501 Token::Value op = Token::ADD; 1503 Token::Value op = Token::ADD;
1502 GenericBinaryOpStub stub(op, mode, NO_SMI_CODE_IN_STUB, TypeInfo::Unknown()); 1504 GenericBinaryOpStub stub(op, mode, NO_SMI_CODE_IN_STUB, TypeInfo::Unknown());
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 __ CallStub(&stub); 2709 __ CallStub(&stub);
2708 Apply(context_, eax); 2710 Apply(context_, eax);
2709 } 2711 }
2710 2712
2711 2713
2712 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2714 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2713 ASSERT(args->length() == 1); 2715 ASSERT(args->length() == 1);
2714 2716
2715 VisitForValue(args->at(0), kAccumulator); // Load the object. 2717 VisitForValue(args->at(0), kAccumulator); // Load the object.
2716 2718
2717 Label done; 2719 NearLabel done;
2718 // If the object is a smi return the object. 2720 // If the object is a smi return the object.
2719 __ test(eax, Immediate(kSmiTagMask)); 2721 __ test(eax, Immediate(kSmiTagMask));
2720 __ j(zero, &done); 2722 __ j(zero, &done);
2721 // If the object is not a value type, return the object. 2723 // If the object is not a value type, return the object.
2722 __ CmpObjectType(eax, JS_VALUE_TYPE, ebx); 2724 __ CmpObjectType(eax, JS_VALUE_TYPE, ebx);
2723 __ j(not_equal, &done); 2725 __ j(not_equal, &done);
2724 __ mov(eax, FieldOperand(eax, JSValue::kValueOffset)); 2726 __ mov(eax, FieldOperand(eax, JSValue::kValueOffset));
2725 2727
2726 __ bind(&done); 2728 __ bind(&done);
2727 Apply(context_, eax); 2729 Apply(context_, eax);
(...skipping 10 matching lines...) Expand all
2738 } 2740 }
2739 2741
2740 2742
2741 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2743 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2742 ASSERT(args->length() == 2); 2744 ASSERT(args->length() == 2);
2743 2745
2744 VisitForValue(args->at(0), kStack); // Load the object. 2746 VisitForValue(args->at(0), kStack); // Load the object.
2745 VisitForValue(args->at(1), kAccumulator); // Load the value. 2747 VisitForValue(args->at(1), kAccumulator); // Load the value.
2746 __ pop(ebx); // eax = value. ebx = object. 2748 __ pop(ebx); // eax = value. ebx = object.
2747 2749
2748 Label done; 2750 NearLabel done;
2749 // If the object is a smi, return the value. 2751 // If the object is a smi, return the value.
2750 __ test(ebx, Immediate(kSmiTagMask)); 2752 __ test(ebx, Immediate(kSmiTagMask));
2751 __ j(zero, &done); 2753 __ j(zero, &done);
2752 2754
2753 // If the object is not a value type, return the value. 2755 // If the object is not a value type, return the value.
2754 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 2756 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
2755 __ j(not_equal, &done); 2757 __ j(not_equal, &done);
2756 2758
2757 // Store the value. 2759 // Store the value.
2758 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax); 2760 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax);
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 break; 3268 break;
3267 } 3269 }
3268 3270
3269 case Token::BIT_NOT: { 3271 case Token::BIT_NOT: {
3270 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); 3272 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
3271 // The generic unary operation stub expects the argument to be 3273 // The generic unary operation stub expects the argument to be
3272 // in the accumulator register eax. 3274 // in the accumulator register eax.
3273 VisitForValue(expr->expression(), kAccumulator); 3275 VisitForValue(expr->expression(), kAccumulator);
3274 Label done; 3276 Label done;
3275 if (ShouldInlineSmiCase(expr->op())) { 3277 if (ShouldInlineSmiCase(expr->op())) {
3276 Label call_stub; 3278 NearLabel call_stub;
3277 __ test(eax, Immediate(kSmiTagMask)); 3279 __ test(eax, Immediate(kSmiTagMask));
3278 __ j(not_zero, &call_stub); 3280 __ j(not_zero, &call_stub);
3279 __ lea(eax, Operand(eax, kSmiTagMask)); 3281 __ lea(eax, Operand(eax, kSmiTagMask));
3280 __ not_(eax); 3282 __ not_(eax);
3281 __ jmp(&done); 3283 __ jmp(&done);
3282 __ bind(&call_stub); 3284 __ bind(&call_stub);
3283 } 3285 }
3284 bool overwrite = expr->expression()->ResultOverwriteAllowed(); 3286 bool overwrite = expr->expression()->ResultOverwriteAllowed();
3285 UnaryOverwriteMode mode = 3287 UnaryOverwriteMode mode =
3286 overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 3288 overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3341 } else { 3343 } else {
3342 VisitForValue(prop->obj(), kStack); 3344 VisitForValue(prop->obj(), kStack);
3343 VisitForValue(prop->key(), kAccumulator); 3345 VisitForValue(prop->key(), kAccumulator);
3344 __ mov(edx, Operand(esp, 0)); 3346 __ mov(edx, Operand(esp, 0));
3345 __ push(eax); 3347 __ push(eax);
3346 EmitKeyedPropertyLoad(prop); 3348 EmitKeyedPropertyLoad(prop);
3347 } 3349 }
3348 } 3350 }
3349 3351
3350 // Call ToNumber only if operand is not a smi. 3352 // Call ToNumber only if operand is not a smi.
3351 Label no_conversion; 3353 NearLabel no_conversion;
3352 if (ShouldInlineSmiCase(expr->op())) { 3354 if (ShouldInlineSmiCase(expr->op())) {
3353 __ test(eax, Immediate(kSmiTagMask)); 3355 __ test(eax, Immediate(kSmiTagMask));
3354 __ j(zero, &no_conversion); 3356 __ j(zero, &no_conversion);
3355 } 3357 }
3356 __ push(eax); 3358 __ push(eax);
3357 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); 3359 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
3358 __ bind(&no_conversion); 3360 __ bind(&no_conversion);
3359 3361
3360 // Save result for postfix expressions. 3362 // Save result for postfix expressions.
3361 if (expr->is_postfix()) { 3363 if (expr->is_postfix()) {
(...skipping 17 matching lines...) Expand all
3379 break; 3381 break;
3380 case KEYED_PROPERTY: 3382 case KEYED_PROPERTY:
3381 __ mov(Operand(esp, 2 * kPointerSize), eax); 3383 __ mov(Operand(esp, 2 * kPointerSize), eax);
3382 break; 3384 break;
3383 } 3385 }
3384 break; 3386 break;
3385 } 3387 }
3386 } 3388 }
3387 3389
3388 // Inline smi case if we are in a loop. 3390 // Inline smi case if we are in a loop.
3389 Label stub_call, done; 3391 NearLabel stub_call;
3392 Label done;
3390 if (ShouldInlineSmiCase(expr->op())) { 3393 if (ShouldInlineSmiCase(expr->op())) {
3391 if (expr->op() == Token::INC) { 3394 if (expr->op() == Token::INC) {
3392 __ add(Operand(eax), Immediate(Smi::FromInt(1))); 3395 __ add(Operand(eax), Immediate(Smi::FromInt(1)));
3393 } else { 3396 } else {
3394 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); 3397 __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
3395 } 3398 }
3396 __ j(overflow, &stub_call); 3399 __ j(overflow, &stub_call);
3397 // We could eliminate this smi check if we split the code at 3400 // We could eliminate this smi check if we split the code at
3398 // the first smi check before calling ToNumber. 3401 // the first smi check before calling ToNumber.
3399 __ test(eax, Immediate(kSmiTagMask)); 3402 __ test(eax, Immediate(kSmiTagMask));
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 cc = greater_equal; 3669 cc = greater_equal;
3667 __ pop(edx); 3670 __ pop(edx);
3668 break; 3671 break;
3669 case Token::IN: 3672 case Token::IN:
3670 case Token::INSTANCEOF: 3673 case Token::INSTANCEOF:
3671 default: 3674 default:
3672 UNREACHABLE(); 3675 UNREACHABLE();
3673 } 3676 }
3674 3677
3675 if (ShouldInlineSmiCase(op)) { 3678 if (ShouldInlineSmiCase(op)) {
3676 Label slow_case; 3679 NearLabel slow_case;
3677 __ mov(ecx, Operand(edx)); 3680 __ mov(ecx, Operand(edx));
3678 __ or_(ecx, Operand(eax)); 3681 __ or_(ecx, Operand(eax));
3679 __ test(ecx, Immediate(kSmiTagMask)); 3682 __ test(ecx, Immediate(kSmiTagMask));
3680 __ j(not_zero, &slow_case, not_taken); 3683 __ j(not_zero, &slow_case, not_taken);
3681 __ cmp(edx, Operand(eax)); 3684 __ cmp(edx, Operand(eax));
3682 Split(cc, if_true, if_false, NULL); 3685 Split(cc, if_true, if_false, NULL);
3683 __ bind(&slow_case); 3686 __ bind(&slow_case);
3684 } 3687 }
3685 3688
3686 CompareStub stub(cc, strict); 3689 CompareStub stub(cc, strict);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3776 // And return. 3779 // And return.
3777 __ ret(0); 3780 __ ret(0);
3778 } 3781 }
3779 3782
3780 3783
3781 #undef __ 3784 #undef __
3782 3785
3783 } } // namespace v8::internal 3786 } } // namespace v8::internal
3784 3787
3785 #endif // V8_TARGET_ARCH_IA32 3788 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698