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

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

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month 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 | « src/ia32/disasm-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 Comment cmnt(masm_, "[ Declarations"); 259 Comment cmnt(masm_, "[ Declarations");
260 scope()->VisitIllegalRedeclaration(this); 260 scope()->VisitIllegalRedeclaration(this);
261 261
262 } else { 262 } else {
263 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); 263 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
264 { Comment cmnt(masm_, "[ Declarations"); 264 { Comment cmnt(masm_, "[ Declarations");
265 // For named function expressions, declare the function name as a 265 // For named function expressions, declare the function name as a
266 // constant. 266 // constant.
267 if (scope()->is_function_scope() && scope()->function() != NULL) { 267 if (scope()->is_function_scope() && scope()->function() != NULL) {
268 int ignored = 0; 268 int ignored = 0;
269 EmitDeclaration(scope()->function(), CONST, NULL, &ignored); 269 VariableProxy* proxy = scope()->function();
270 ASSERT(proxy->var()->mode() == CONST ||
271 proxy->var()->mode() == CONST_HARMONY);
272 EmitDeclaration(proxy, proxy->var()->mode(), NULL, &ignored);
270 } 273 }
271 VisitDeclarations(scope()->declarations()); 274 VisitDeclarations(scope()->declarations());
272 } 275 }
273 276
274 { Comment cmnt(masm_, "[ Stack check"); 277 { Comment cmnt(masm_, "[ Stack check");
275 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); 278 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
276 Label ok; 279 Label ok;
277 ExternalReference stack_limit = 280 ExternalReference stack_limit =
278 ExternalReference::address_of_stack_limit(isolate()); 281 ExternalReference::address_of_stack_limit(isolate());
279 __ cmp(esp, Operand::StaticVariable(stack_limit)); 282 __ cmp(esp, Operand::StaticVariable(stack_limit));
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 707
705 708
706 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, 709 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
707 VariableMode mode, 710 VariableMode mode,
708 FunctionLiteral* function, 711 FunctionLiteral* function,
709 int* global_count) { 712 int* global_count) {
710 // If it was not possible to allocate the variable at compile time, we 713 // If it was not possible to allocate the variable at compile time, we
711 // need to "declare" it at runtime to make sure it actually exists in the 714 // need to "declare" it at runtime to make sure it actually exists in the
712 // local context. 715 // local context.
713 Variable* variable = proxy->var(); 716 Variable* variable = proxy->var();
717 bool binding_needs_init =
718 mode == CONST || mode == CONST_HARMONY || mode == LET;
714 switch (variable->location()) { 719 switch (variable->location()) {
715 case Variable::UNALLOCATED: 720 case Variable::UNALLOCATED:
716 ++(*global_count); 721 ++(*global_count);
717 break; 722 break;
718 723
719 case Variable::PARAMETER: 724 case Variable::PARAMETER:
720 case Variable::LOCAL: 725 case Variable::LOCAL:
721 if (function != NULL) { 726 if (function != NULL) {
722 Comment cmnt(masm_, "[ Declaration"); 727 Comment cmnt(masm_, "[ Declaration");
723 VisitForAccumulatorValue(function); 728 VisitForAccumulatorValue(function);
724 __ mov(StackOperand(variable), result_register()); 729 __ mov(StackOperand(variable), result_register());
725 } else if (mode == CONST || mode == LET) { 730 } else if (binding_needs_init) {
726 Comment cmnt(masm_, "[ Declaration"); 731 Comment cmnt(masm_, "[ Declaration");
727 __ mov(StackOperand(variable), 732 __ mov(StackOperand(variable),
728 Immediate(isolate()->factory()->the_hole_value())); 733 Immediate(isolate()->factory()->the_hole_value()));
729 } 734 }
730 break; 735 break;
731 736
732 case Variable::CONTEXT: 737 case Variable::CONTEXT:
733 // The variable in the decl always resides in the current function 738 // The variable in the decl always resides in the current function
734 // context. 739 // context.
735 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 740 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
(...skipping 11 matching lines...) Expand all
747 __ mov(ContextOperand(esi, variable->index()), result_register()); 752 __ mov(ContextOperand(esi, variable->index()), result_register());
748 // We know that we have written a function, which is not a smi. 753 // We know that we have written a function, which is not a smi.
749 __ RecordWriteContextSlot(esi, 754 __ RecordWriteContextSlot(esi,
750 Context::SlotOffset(variable->index()), 755 Context::SlotOffset(variable->index()),
751 result_register(), 756 result_register(),
752 ecx, 757 ecx,
753 kDontSaveFPRegs, 758 kDontSaveFPRegs,
754 EMIT_REMEMBERED_SET, 759 EMIT_REMEMBERED_SET,
755 OMIT_SMI_CHECK); 760 OMIT_SMI_CHECK);
756 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 761 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
757 } else if (mode == CONST || mode == LET) { 762 } else if (binding_needs_init) {
758 Comment cmnt(masm_, "[ Declaration"); 763 Comment cmnt(masm_, "[ Declaration");
759 __ mov(ContextOperand(esi, variable->index()), 764 __ mov(ContextOperand(esi, variable->index()),
760 Immediate(isolate()->factory()->the_hole_value())); 765 Immediate(isolate()->factory()->the_hole_value()));
761 // No write barrier since the hole value is in old space. 766 // No write barrier since the hole value is in old space.
762 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 767 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
763 } 768 }
764 break; 769 break;
765 770
766 case Variable::LOOKUP: { 771 case Variable::LOOKUP: {
767 Comment cmnt(masm_, "[ Declaration"); 772 Comment cmnt(masm_, "[ Declaration");
768 __ push(esi); 773 __ push(esi);
769 __ push(Immediate(variable->name())); 774 __ push(Immediate(variable->name()));
770 // Declaration nodes are always introduced in one of three modes. 775 // Declaration nodes are always introduced in one of four modes.
771 ASSERT(mode == VAR || mode == CONST || mode == LET); 776 ASSERT(mode == VAR ||
772 PropertyAttributes attr = (mode == CONST) ? READ_ONLY : NONE; 777 mode == CONST ||
778 mode == CONST_HARMONY ||
779 mode == LET);
780 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
781 ? READ_ONLY : NONE;
773 __ push(Immediate(Smi::FromInt(attr))); 782 __ push(Immediate(Smi::FromInt(attr)));
774 // Push initial value, if any. 783 // Push initial value, if any.
775 // Note: For variables we must not push an initial value (such as 784 // Note: For variables we must not push an initial value (such as
776 // 'undefined') because we may have a (legal) redeclaration and we 785 // 'undefined') because we may have a (legal) redeclaration and we
777 // must not destroy the current value. 786 // must not destroy the current value.
778 increment_stack_height(3); 787 increment_stack_height(3);
779 if (function != NULL) { 788 if (function != NULL) {
780 VisitForStackValue(function); 789 VisitForStackValue(function);
781 } else if (mode == CONST || mode == LET) { 790 } else if (binding_needs_init) {
782 __ push(Immediate(isolate()->factory()->the_hole_value())); 791 __ push(Immediate(isolate()->factory()->the_hole_value()));
783 increment_stack_height(); 792 increment_stack_height();
784 } else { 793 } else {
785 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. 794 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value.
786 increment_stack_height(); 795 increment_stack_height();
787 } 796 }
788 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 797 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
789 decrement_stack_height(4); 798 decrement_stack_height(4);
790 break; 799 break;
791 } 800 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 __ JumpIfSmi(eax, &convert, Label::kNear); 922 __ JumpIfSmi(eax, &convert, Label::kNear);
914 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 923 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
915 __ j(above_equal, &done_convert, Label::kNear); 924 __ j(above_equal, &done_convert, Label::kNear);
916 __ bind(&convert); 925 __ bind(&convert);
917 __ push(eax); 926 __ push(eax);
918 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 927 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
919 __ bind(&done_convert); 928 __ bind(&done_convert);
920 __ push(eax); 929 __ push(eax);
921 increment_stack_height(); 930 increment_stack_height();
922 931
932 // Check for proxies.
933 Label call_runtime;
934 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
935 __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx);
936 __ j(below_equal, &call_runtime);
937
923 // Check cache validity in generated code. This is a fast case for 938 // Check cache validity in generated code. This is a fast case for
924 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 939 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
925 // guarantee cache validity, call the runtime system to check cache 940 // guarantee cache validity, call the runtime system to check cache
926 // validity or get the property names in a fixed array. 941 // validity or get the property names in a fixed array.
927 Label next, call_runtime; 942 Label next;
928 __ mov(ecx, eax); 943 __ mov(ecx, eax);
929 __ bind(&next); 944 __ bind(&next);
930 945
931 // Check that there are no elements. Register ecx contains the 946 // Check that there are no elements. Register ecx contains the
932 // current JS object we've reached through the prototype chain. 947 // current JS object we've reached through the prototype chain.
933 __ cmp(FieldOperand(ecx, JSObject::kElementsOffset), 948 __ cmp(FieldOperand(ecx, JSObject::kElementsOffset),
934 isolate()->factory()->empty_fixed_array()); 949 isolate()->factory()->empty_fixed_array());
935 __ j(not_equal, &call_runtime); 950 __ j(not_equal, &call_runtime);
936 951
937 // Check that instance descriptors are not empty so that we can 952 // Check that instance descriptors are not empty so that we can
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 1003
989 // Setup the four remaining stack slots. 1004 // Setup the four remaining stack slots.
990 __ push(eax); // Map. 1005 __ push(eax); // Map.
991 __ push(edx); // Enumeration cache. 1006 __ push(edx); // Enumeration cache.
992 __ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset)); 1007 __ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset));
993 __ push(eax); // Enumeration cache length (as smi). 1008 __ push(eax); // Enumeration cache length (as smi).
994 __ push(Immediate(Smi::FromInt(0))); // Initial index. 1009 __ push(Immediate(Smi::FromInt(0))); // Initial index.
995 __ jmp(&loop); 1010 __ jmp(&loop);
996 1011
997 // We got a fixed array in register eax. Iterate through that. 1012 // We got a fixed array in register eax. Iterate through that.
1013 Label non_proxy;
998 __ bind(&fixed_array); 1014 __ bind(&fixed_array);
999 __ push(Immediate(Smi::FromInt(0))); // Map (0) - force slow check. 1015 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
1000 __ push(eax); 1016 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object
1017 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1018 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx);
1019 __ j(above, &non_proxy);
1020 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy
1021 __ bind(&non_proxy);
1022 __ push(ebx); // Smi
1023 __ push(eax); // Array
1001 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); 1024 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
1002 __ push(eax); // Fixed array length (as smi). 1025 __ push(eax); // Fixed array length (as smi).
1003 __ push(Immediate(Smi::FromInt(0))); // Initial index. 1026 __ push(Immediate(Smi::FromInt(0))); // Initial index.
1004 1027
1005 // 1 ~ The object has already been pushed. 1028 // 1 ~ The object has already been pushed.
1006 increment_stack_height(ForIn::kElementCount - 1); 1029 increment_stack_height(ForIn::kElementCount - 1);
1007 // Generate code for doing the condition check. 1030 // Generate code for doing the condition check.
1008 __ bind(&loop); 1031 __ bind(&loop);
1009 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. 1032 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index.
1010 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. 1033 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length.
1011 __ j(above_equal, loop_statement.break_label()); 1034 __ j(above_equal, loop_statement.break_label());
1012 1035
1013 // Get the current entry of the array into register ebx. 1036 // Get the current entry of the array into register ebx.
1014 __ mov(ebx, Operand(esp, 2 * kPointerSize)); 1037 __ mov(ebx, Operand(esp, 2 * kPointerSize));
1015 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); 1038 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize));
1016 1039
1017 // Get the expected map from the stack or a zero map in the 1040 // Get the expected map from the stack or a smi in the
1018 // permanent slow case into register edx. 1041 // permanent slow case into register edx.
1019 __ mov(edx, Operand(esp, 3 * kPointerSize)); 1042 __ mov(edx, Operand(esp, 3 * kPointerSize));
1020 1043
1021 // Check if the expected map still matches that of the enumerable. 1044 // Check if the expected map still matches that of the enumerable.
1022 // If not, we have to filter the key. 1045 // If not, we may have to filter the key.
1023 Label update_each; 1046 Label update_each;
1024 __ mov(ecx, Operand(esp, 4 * kPointerSize)); 1047 __ mov(ecx, Operand(esp, 4 * kPointerSize));
1025 __ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset)); 1048 __ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset));
1026 __ j(equal, &update_each, Label::kNear); 1049 __ j(equal, &update_each, Label::kNear);
1027 1050
1051 // For proxies, no filtering is done.
1052 // TODO(rossberg): What if only a prototype is a proxy? Not specified yet.
1053 ASSERT(Smi::FromInt(0) == 0);
1054 __ test(edx, edx);
1055 __ j(zero, &update_each);
1056
1028 // Convert the entry to a string or null if it isn't a property 1057 // Convert the entry to a string or null if it isn't a property
1029 // anymore. If the property has been removed while iterating, we 1058 // anymore. If the property has been removed while iterating, we
1030 // just skip it. 1059 // just skip it.
1031 __ push(ecx); // Enumerable. 1060 __ push(ecx); // Enumerable.
1032 __ push(ebx); // Current entry. 1061 __ push(ebx); // Current entry.
1033 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 1062 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
1034 __ test(eax, eax); 1063 __ test(eax, eax);
1035 __ j(equal, loop_statement.continue_label()); 1064 __ j(equal, loop_statement.continue_label());
1036 __ mov(ebx, eax); 1065 __ mov(ebx, eax);
1037 1066
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 // space for nested functions that don't need literals cloning. If 1101 // space for nested functions that don't need literals cloning. If
1073 // we're running with the --always-opt or the --prepare-always-opt 1102 // we're running with the --always-opt or the --prepare-always-opt
1074 // flag, we need to use the runtime function so that the new function 1103 // flag, we need to use the runtime function so that the new function
1075 // we are creating here gets a chance to have its code optimized and 1104 // we are creating here gets a chance to have its code optimized and
1076 // doesn't just get a copy of the existing unoptimized code. 1105 // doesn't just get a copy of the existing unoptimized code.
1077 if (!FLAG_always_opt && 1106 if (!FLAG_always_opt &&
1078 !FLAG_prepare_always_opt && 1107 !FLAG_prepare_always_opt &&
1079 !pretenure && 1108 !pretenure &&
1080 scope()->is_function_scope() && 1109 scope()->is_function_scope() &&
1081 info->num_literals() == 0) { 1110 info->num_literals() == 0) {
1082 FastNewClosureStub stub(info->strict_mode() ? kStrictMode : kNonStrictMode); 1111 FastNewClosureStub stub(info->strict_mode_flag());
1083 __ push(Immediate(info)); 1112 __ push(Immediate(info));
1084 __ CallStub(&stub); 1113 __ CallStub(&stub);
1085 } else { 1114 } else {
1086 __ push(esi); 1115 __ push(esi);
1087 __ push(Immediate(info)); 1116 __ push(Immediate(info));
1088 __ push(Immediate(pretenure 1117 __ push(Immediate(pretenure
1089 ? isolate()->factory()->true_value() 1118 ? isolate()->factory()->true_value()
1090 : isolate()->factory()->false_value())); 1119 : isolate()->factory()->false_value()));
1091 __ CallRuntime(Runtime::kNewClosure, 3); 1120 __ CallRuntime(Runtime::kNewClosure, 3);
1092 } 1121 }
1093 context()->Plug(eax); 1122 context()->Plug(eax);
1094 } 1123 }
1095 1124
1096 1125
1097 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1126 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1098 Comment cmnt(masm_, "[ VariableProxy"); 1127 Comment cmnt(masm_, "[ VariableProxy");
1099 EmitVariableLoad(expr); 1128 EmitVariableLoad(expr);
1100 } 1129 }
1101 1130
1102 1131
1103 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, 1132 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
1104 TypeofState typeof_state, 1133 TypeofState typeof_state,
1105 Label* slow) { 1134 Label* slow) {
1106 Register context = esi; 1135 Register context = esi;
1107 Register temp = edx; 1136 Register temp = edx;
1108 1137
1109 Scope* s = scope(); 1138 Scope* s = scope();
1110 while (s != NULL) { 1139 while (s != NULL) {
1111 if (s->num_heap_slots() > 0) { 1140 if (s->num_heap_slots() > 0) {
1112 if (s->calls_eval()) { 1141 if (s->calls_non_strict_eval()) {
1113 // Check that extension is NULL. 1142 // Check that extension is NULL.
1114 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), 1143 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
1115 Immediate(0)); 1144 Immediate(0));
1116 __ j(not_equal, slow); 1145 __ j(not_equal, slow);
1117 } 1146 }
1118 // Load next context in chain. 1147 // Load next context in chain.
1119 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); 1148 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1120 // Walk the rest of the chain without clobbering esi. 1149 // Walk the rest of the chain without clobbering esi.
1121 context = temp; 1150 context = temp;
1122 } 1151 }
1123 // If no outer scope calls eval, we do not need to check more 1152 // If no outer scope calls eval, we do not need to check more
1124 // context extensions. If we have reached an eval scope, we check 1153 // context extensions. If we have reached an eval scope, we check
1125 // all extensions from this point. 1154 // all extensions from this point.
1126 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; 1155 if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break;
1127 s = s->outer_scope(); 1156 s = s->outer_scope();
1128 } 1157 }
1129 1158
1130 if (s != NULL && s->is_eval_scope()) { 1159 if (s != NULL && s->is_eval_scope()) {
1131 // Loop up the context chain. There is no frame effect so it is 1160 // Loop up the context chain. There is no frame effect so it is
1132 // safe to use raw labels here. 1161 // safe to use raw labels here.
1133 Label next, fast; 1162 Label next, fast;
1134 if (!context.is(temp)) { 1163 if (!context.is(temp)) {
1135 __ mov(temp, context); 1164 __ mov(temp, context);
1136 } 1165 }
(...skipping 24 matching lines...) Expand all
1161 1190
1162 1191
1163 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1192 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1164 Label* slow) { 1193 Label* slow) {
1165 ASSERT(var->IsContextSlot()); 1194 ASSERT(var->IsContextSlot());
1166 Register context = esi; 1195 Register context = esi;
1167 Register temp = ebx; 1196 Register temp = ebx;
1168 1197
1169 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1198 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1170 if (s->num_heap_slots() > 0) { 1199 if (s->num_heap_slots() > 0) {
1171 if (s->calls_eval()) { 1200 if (s->calls_non_strict_eval()) {
1172 // Check that extension is NULL. 1201 // Check that extension is NULL.
1173 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), 1202 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
1174 Immediate(0)); 1203 Immediate(0));
1175 __ j(not_equal, slow); 1204 __ j(not_equal, slow);
1176 } 1205 }
1177 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); 1206 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX));
1178 // Walk the rest of the chain without clobbering esi. 1207 // Walk the rest of the chain without clobbering esi.
1179 context = temp; 1208 context = temp;
1180 } 1209 }
1181 } 1210 }
(...skipping 17 matching lines...) Expand all
1199 // introducing variables. In those cases, we do not want to 1228 // introducing variables. In those cases, we do not want to
1200 // perform a runtime call for all variables in the scope 1229 // perform a runtime call for all variables in the scope
1201 // containing the eval. 1230 // containing the eval.
1202 if (var->mode() == DYNAMIC_GLOBAL) { 1231 if (var->mode() == DYNAMIC_GLOBAL) {
1203 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1232 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1204 __ jmp(done); 1233 __ jmp(done);
1205 } else if (var->mode() == DYNAMIC_LOCAL) { 1234 } else if (var->mode() == DYNAMIC_LOCAL) {
1206 Variable* local = var->local_if_not_shadowed(); 1235 Variable* local = var->local_if_not_shadowed();
1207 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1236 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1208 if (local->mode() == CONST || 1237 if (local->mode() == CONST ||
1238 local->mode() == CONST_HARMONY ||
1209 local->mode() == LET) { 1239 local->mode() == LET) {
1210 __ cmp(eax, isolate()->factory()->the_hole_value()); 1240 __ cmp(eax, isolate()->factory()->the_hole_value());
1211 __ j(not_equal, done); 1241 __ j(not_equal, done);
1212 if (local->mode() == CONST) { 1242 if (local->mode() == CONST) {
1213 __ mov(eax, isolate()->factory()->undefined_value()); 1243 __ mov(eax, isolate()->factory()->undefined_value());
1214 } else { // LET 1244 } else { // LET || CONST_HARMONY
1215 __ push(Immediate(var->name())); 1245 __ push(Immediate(var->name()));
1216 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1246 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1217 } 1247 }
1218 } 1248 }
1219 __ jmp(done); 1249 __ jmp(done);
1220 } 1250 }
1221 } 1251 }
1222 1252
1223 1253
1224 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1254 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
(...skipping 15 matching lines...) Expand all
1240 context()->Plug(eax); 1270 context()->Plug(eax);
1241 break; 1271 break;
1242 } 1272 }
1243 1273
1244 case Variable::PARAMETER: 1274 case Variable::PARAMETER:
1245 case Variable::LOCAL: 1275 case Variable::LOCAL:
1246 case Variable::CONTEXT: { 1276 case Variable::CONTEXT: {
1247 Comment cmnt(masm_, var->IsContextSlot() 1277 Comment cmnt(masm_, var->IsContextSlot()
1248 ? "Context variable" 1278 ? "Context variable"
1249 : "Stack variable"); 1279 : "Stack variable");
1250 if (var->mode() != LET && var->mode() != CONST) { 1280 if (!var->binding_needs_init()) {
1251 context()->Plug(var); 1281 context()->Plug(var);
1252 } else { 1282 } else {
1253 // Let and const need a read barrier. 1283 // Let and const need a read barrier.
1254 Label done; 1284 Label done;
1255 GetVar(eax, var); 1285 GetVar(eax, var);
1256 __ cmp(eax, isolate()->factory()->the_hole_value()); 1286 __ cmp(eax, isolate()->factory()->the_hole_value());
1257 __ j(not_equal, &done, Label::kNear); 1287 __ j(not_equal, &done, Label::kNear);
1258 if (var->mode() == LET) { 1288 if (var->mode() == LET || var->mode() == CONST_HARMONY) {
1289 // Throw a reference error when using an uninitialized let/const
1290 // binding in harmony mode.
1259 __ push(Immediate(var->name())); 1291 __ push(Immediate(var->name()));
1260 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1292 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1261 } else { // CONST 1293 } else {
1294 // Uninitalized const bindings outside of harmony mode are unholed.
1295 ASSERT(var->mode() == CONST);
1262 __ mov(eax, isolate()->factory()->undefined_value()); 1296 __ mov(eax, isolate()->factory()->undefined_value());
1263 } 1297 }
1264 __ bind(&done); 1298 __ bind(&done);
1265 context()->Plug(eax); 1299 context()->Plug(eax);
1266 } 1300 }
1267 break; 1301 break;
1268 } 1302 }
1269 1303
1270 case Variable::LOOKUP: { 1304 case Variable::LOOKUP: {
1271 Label done, slow; 1305 Label done, slow;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 context()->Plug(eax); 1475 context()->Plug(eax);
1442 } 1476 }
1443 } 1477 }
1444 1478
1445 1479
1446 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1480 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1447 Comment cmnt(masm_, "[ ArrayLiteral"); 1481 Comment cmnt(masm_, "[ ArrayLiteral");
1448 1482
1449 ZoneList<Expression*>* subexprs = expr->values(); 1483 ZoneList<Expression*>* subexprs = expr->values();
1450 int length = subexprs->length(); 1484 int length = subexprs->length();
1485 Handle<FixedArray> constant_elements = expr->constant_elements();
1486 ASSERT_EQ(2, constant_elements->length());
1487 ElementsKind constant_elements_kind =
1488 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
1489 Handle<FixedArrayBase> constant_elements_values(
1490 FixedArrayBase::cast(constant_elements->get(1)));
1451 1491
1452 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1492 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1453 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); 1493 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
1454 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1494 __ push(Immediate(Smi::FromInt(expr->literal_index())));
1455 __ push(Immediate(expr->constant_elements())); 1495 __ push(Immediate(constant_elements));
1456 if (expr->constant_elements()->map() == 1496 if (constant_elements_values->map() ==
1457 isolate()->heap()->fixed_cow_array_map()) { 1497 isolate()->heap()->fixed_cow_array_map()) {
1458 ASSERT(expr->depth() == 1); 1498 ASSERT(expr->depth() == 1);
1459 FastCloneShallowArrayStub stub( 1499 FastCloneShallowArrayStub stub(
1460 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); 1500 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
1461 __ CallStub(&stub); 1501 __ CallStub(&stub);
1462 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); 1502 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
1463 } else if (expr->depth() > 1) { 1503 } else if (expr->depth() > 1) {
1464 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1504 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
1465 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { 1505 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1466 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 1506 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1467 } else { 1507 } else {
1468 FastCloneShallowArrayStub stub( 1508 ASSERT(constant_elements_kind == FAST_ELEMENTS ||
1469 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); 1509 constant_elements_kind == FAST_SMI_ONLY_ELEMENTS ||
1510 FLAG_smi_only_arrays);
1511 FastCloneShallowArrayStub::Mode mode =
1512 constant_elements_kind == FAST_DOUBLE_ELEMENTS
1513 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
1514 : FastCloneShallowArrayStub::CLONE_ELEMENTS;
1515 FastCloneShallowArrayStub stub(mode, length);
1470 __ CallStub(&stub); 1516 __ CallStub(&stub);
1471 } 1517 }
1472 1518
1473 bool result_saved = false; // Is the result saved to the stack? 1519 bool result_saved = false; // Is the result saved to the stack?
1474 1520
1475 // Emit code to evaluate all the non-constant subexpressions and to store 1521 // Emit code to evaluate all the non-constant subexpressions and to store
1476 // them into the newly cloned array. 1522 // them into the newly cloned array.
1477 for (int i = 0; i < length; i++) { 1523 for (int i = 0; i < length; i++) {
1478 Expression* subexpr = subexprs->at(i); 1524 Expression* subexpr = subexprs->at(i);
1479 // If the subexpression is a literal or a simple materialized literal it 1525 // If the subexpression is a literal or a simple materialized literal it
1480 // is already set in the cloned array. 1526 // is already set in the cloned array.
1481 if (subexpr->AsLiteral() != NULL || 1527 if (subexpr->AsLiteral() != NULL ||
1482 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1528 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1483 continue; 1529 continue;
1484 } 1530 }
1485 1531
1486 if (!result_saved) { 1532 if (!result_saved) {
1487 __ push(eax); 1533 __ push(eax);
1488 result_saved = true; 1534 result_saved = true;
1489 increment_stack_height(); 1535 increment_stack_height();
1490 } 1536 }
1491 VisitForAccumulatorValue(subexpr); 1537 VisitForAccumulatorValue(subexpr);
1492 1538
1493 // Store the subexpression value in the array's elements. 1539 // Store the subexpression value in the array's elements.
1494 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 1540 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
1541 __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
1495 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1542 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
1496 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1543 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1544
1545 Label element_done;
1546 Label double_elements;
1547 Label smi_element;
1548 Label slow_elements;
1549 Label fast_elements;
1550 __ CheckFastElements(edi, &double_elements);
1551
1552 // FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS
1553 __ JumpIfSmi(result_register(), &smi_element);
1554 __ CheckFastSmiOnlyElements(edi, &fast_elements, Label::kNear);
1555
1556 // Store into the array literal requires a elements transition. Call into
1557 // the runtime.
1558 __ bind(&slow_elements);
1559 __ push(Operand(esp, 0)); // Copy of array literal.
1560 __ push(Immediate(Smi::FromInt(i)));
1561 __ push(result_register());
1562 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
1563 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); // Strict mode.
1564 __ CallRuntime(Runtime::kSetProperty, 5);
1565 __ jmp(&element_done);
1566
1567 // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
1568 __ bind(&double_elements);
1569 __ mov(ecx, Immediate(Smi::FromInt(i)));
1570 __ StoreNumberToDoubleElements(result_register(),
1571 ebx,
1572 ecx,
1573 edx,
1574 xmm0,
1575 &slow_elements,
1576 false);
1577 __ jmp(&element_done);
1578
1579 // Array literal has ElementsKind of FAST_ELEMENTS and value is an object.
1580 __ bind(&fast_elements);
1497 __ mov(FieldOperand(ebx, offset), result_register()); 1581 __ mov(FieldOperand(ebx, offset), result_register());
1498
1499 Label no_map_change;
1500 __ JumpIfSmi(result_register(), &no_map_change);
1501 // Update the write barrier for the array store. 1582 // Update the write barrier for the array store.
1502 __ RecordWriteField(ebx, offset, result_register(), ecx, 1583 __ RecordWriteField(ebx, offset, result_register(), ecx,
1503 kDontSaveFPRegs, 1584 kDontSaveFPRegs,
1504 EMIT_REMEMBERED_SET, 1585 EMIT_REMEMBERED_SET,
1505 OMIT_SMI_CHECK); 1586 OMIT_SMI_CHECK);
1506 __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset)); 1587 __ jmp(&element_done);
1507 __ CheckFastSmiOnlyElements(edi, &no_map_change, Label::kNear); 1588
1508 __ push(Operand(esp, 0)); 1589 // Array literal has ElementsKind of FAST_SMI_ONLY_ELEMENTS or
1509 __ CallRuntime(Runtime::kNonSmiElementStored, 1); 1590 // FAST_ELEMENTS, and value is Smi.
1510 __ bind(&no_map_change); 1591 __ bind(&smi_element);
1592 __ mov(FieldOperand(ebx, offset), result_register());
1593 // Fall through
1594
1595 __ bind(&element_done);
1511 1596
1512 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1597 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1513 } 1598 }
1514 1599
1515 if (result_saved) { 1600 if (result_saved) {
1516 context()->PlugTOS(); 1601 context()->PlugTOS();
1517 } else { 1602 } else {
1518 context()->Plug(eax); 1603 context()->Plug(eax);
1519 } 1604 }
1520 } 1605 }
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1883 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1968 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1884 __ bind(&assign); 1969 __ bind(&assign);
1885 __ mov(location, eax); 1970 __ mov(location, eax);
1886 if (var->IsContextSlot()) { 1971 if (var->IsContextSlot()) {
1887 __ mov(edx, eax); 1972 __ mov(edx, eax);
1888 int offset = Context::SlotOffset(var->index()); 1973 int offset = Context::SlotOffset(var->index());
1889 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 1974 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
1890 } 1975 }
1891 } 1976 }
1892 1977
1893 } else if (var->mode() != CONST) { 1978 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
1894 // Assignment to var or initializing assignment to let. 1979 // Assignment to var or initializing assignment to let/const
1980 // in harmony mode.
1895 if (var->IsStackAllocated() || var->IsContextSlot()) { 1981 if (var->IsStackAllocated() || var->IsContextSlot()) {
1896 MemOperand location = VarOperand(var, ecx); 1982 MemOperand location = VarOperand(var, ecx);
1897 if (FLAG_debug_code && op == Token::INIT_LET) { 1983 if (FLAG_debug_code && op == Token::INIT_LET) {
1898 // Check for an uninitialized let binding. 1984 // Check for an uninitialized let binding.
1899 __ mov(edx, location); 1985 __ mov(edx, location);
1900 __ cmp(edx, isolate()->factory()->the_hole_value()); 1986 __ cmp(edx, isolate()->factory()->the_hole_value());
1901 __ Check(equal, "Let binding re-initialization."); 1987 __ Check(equal, "Let binding re-initialization.");
1902 } 1988 }
1903 // Perform the assignment. 1989 // Perform the assignment.
1904 __ mov(location, eax); 1990 __ mov(location, eax);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2097 } 2183 }
2098 // Record source position for debugger. 2184 // Record source position for debugger.
2099 SetSourcePosition(expr->position()); 2185 SetSourcePosition(expr->position());
2100 2186
2101 // Record call targets in unoptimized code, but not in the snapshot. 2187 // Record call targets in unoptimized code, but not in the snapshot.
2102 bool record_call_target = !Serializer::enabled(); 2188 bool record_call_target = !Serializer::enabled();
2103 if (record_call_target) { 2189 if (record_call_target) {
2104 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); 2190 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
2105 } 2191 }
2106 CallFunctionStub stub(arg_count, flags); 2192 CallFunctionStub stub(arg_count, flags);
2107 __ CallStub(&stub); 2193 __ CallStub(&stub, expr->id());
2108 if (record_call_target) { 2194 if (record_call_target) {
2109 // There is a one element cache in the instruction stream. 2195 // There is a one element cache in the instruction stream.
2110 #ifdef DEBUG 2196 #ifdef DEBUG
2111 int return_site_offset = masm()->pc_offset(); 2197 int return_site_offset = masm()->pc_offset();
2112 #endif 2198 #endif
2113 Handle<Object> uninitialized = 2199 Handle<Object> uninitialized =
2114 CallFunctionStub::UninitializedSentinel(isolate()); 2200 CallFunctionStub::UninitializedSentinel(isolate());
2115 Handle<JSGlobalPropertyCell> cell = 2201 Handle<JSGlobalPropertyCell> cell =
2116 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); 2202 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2117 __ test(eax, Immediate(cell)); 2203 __ test(eax, Immediate(cell));
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 __ jmp(&heapnumber_allocated); 2860 __ jmp(&heapnumber_allocated);
2775 2861
2776 __ bind(&slow_allocate_heapnumber); 2862 __ bind(&slow_allocate_heapnumber);
2777 // Allocate a heap number. 2863 // Allocate a heap number.
2778 __ CallRuntime(Runtime::kNumberAlloc, 0); 2864 __ CallRuntime(Runtime::kNumberAlloc, 0);
2779 __ mov(edi, eax); 2865 __ mov(edi, eax);
2780 2866
2781 __ bind(&heapnumber_allocated); 2867 __ bind(&heapnumber_allocated);
2782 2868
2783 __ PrepareCallCFunction(1, ebx); 2869 __ PrepareCallCFunction(1, ebx);
2784 __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); 2870 __ mov(eax, ContextOperand(context_register(), Context::GLOBAL_INDEX));
2785 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 2871 __ mov(eax, FieldOperand(eax, GlobalObject::kGlobalContextOffset));
2786 1); 2872 __ mov(Operand(esp, 0), eax);
2873 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
2787 2874
2788 // Convert 32 random bits in eax to 0.(32 random bits) in a double 2875 // Convert 32 random bits in eax to 0.(32 random bits) in a double
2789 // by computing: 2876 // by computing:
2790 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2877 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2791 // This is implemented on both SSE2 and FPU. 2878 // This is implemented on both SSE2 and FPU.
2792 if (CpuFeatures::IsSupported(SSE2)) { 2879 if (CpuFeatures::IsSupported(SSE2)) {
2793 CpuFeatures::Scope fscope(SSE2); 2880 CpuFeatures::Scope fscope(SSE2);
2794 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 2881 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
2795 __ movd(xmm1, ebx); 2882 __ movd(xmm1, ebx);
2796 __ movd(xmm0, eax); 2883 __ movd(xmm0, eax);
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
4140 break; 4227 break;
4141 } 4228 }
4142 4229
4143 default: { 4230 default: {
4144 VisitForAccumulatorValue(expr->right()); 4231 VisitForAccumulatorValue(expr->right());
4145 Condition cc = no_condition; 4232 Condition cc = no_condition;
4146 switch (op) { 4233 switch (op) {
4147 case Token::EQ_STRICT: 4234 case Token::EQ_STRICT:
4148 case Token::EQ: 4235 case Token::EQ:
4149 cc = equal; 4236 cc = equal;
4150 __ pop(edx);
4151 break; 4237 break;
4152 case Token::LT: 4238 case Token::LT:
4153 cc = less; 4239 cc = less;
4154 __ pop(edx);
4155 break; 4240 break;
4156 case Token::GT: 4241 case Token::GT:
4157 // Reverse left and right sizes to obtain ECMA-262 conversion order. 4242 cc = greater;
4158 cc = less;
4159 __ mov(edx, result_register());
4160 __ pop(eax);
4161 break; 4243 break;
4162 case Token::LTE: 4244 case Token::LTE:
4163 // Reverse left and right sizes to obtain ECMA-262 conversion order. 4245 cc = less_equal;
4164 cc = greater_equal;
4165 __ mov(edx, result_register());
4166 __ pop(eax);
4167 break; 4246 break;
4168 case Token::GTE: 4247 case Token::GTE:
4169 cc = greater_equal; 4248 cc = greater_equal;
4170 __ pop(edx);
4171 break; 4249 break;
4172 case Token::IN: 4250 case Token::IN:
4173 case Token::INSTANCEOF: 4251 case Token::INSTANCEOF:
4174 default: 4252 default:
4175 UNREACHABLE(); 4253 UNREACHABLE();
4176 } 4254 }
4255 __ pop(edx);
4177 decrement_stack_height(); 4256 decrement_stack_height();
4178 4257
4179 bool inline_smi_code = ShouldInlineSmiCase(op); 4258 bool inline_smi_code = ShouldInlineSmiCase(op);
4180 JumpPatchSite patch_site(masm_); 4259 JumpPatchSite patch_site(masm_);
4181 if (inline_smi_code) { 4260 if (inline_smi_code) {
4182 Label slow_case; 4261 Label slow_case;
4183 __ mov(ecx, edx); 4262 __ mov(ecx, edx);
4184 __ or_(ecx, eax); 4263 __ or_(ecx, eax);
4185 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4264 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4186 __ cmp(edx, eax); 4265 __ cmp(edx, eax);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4343 *context_length = 0; 4422 *context_length = 0;
4344 return previous_; 4423 return previous_;
4345 } 4424 }
4346 4425
4347 4426
4348 #undef __ 4427 #undef __
4349 4428
4350 } } // namespace v8::internal 4429 } } // namespace v8::internal
4351 4430
4352 #endif // V8_TARGET_ARCH_IA32 4431 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/disasm-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698