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

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

Issue 546075: First step of refactoring expression contexts in the toplevel code... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 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 2009 the V8 project authors. All rights reserved. 1 // Copyright 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 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 Handle<JSFunction> boilerplate = 768 Handle<JSFunction> boilerplate =
769 Compiler::BuildBoilerplate(expr, script_, this); 769 Compiler::BuildBoilerplate(expr, script_, this);
770 if (HasStackOverflow()) return; 770 if (HasStackOverflow()) return;
771 771
772 ASSERT(boilerplate->IsBoilerplate()); 772 ASSERT(boilerplate->IsBoilerplate());
773 773
774 // Create a new closure. 774 // Create a new closure.
775 __ push(esi); 775 __ push(esi);
776 __ push(Immediate(boilerplate)); 776 __ push(Immediate(boilerplate));
777 __ CallRuntime(Runtime::kNewClosure, 2); 777 __ CallRuntime(Runtime::kNewClosure, 2);
778 Apply(expr->context(), eax); 778 Apply(context_, eax);
779 } 779 }
780 780
781 781
782 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 782 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
783 Comment cmnt(masm_, "[ VariableProxy"); 783 Comment cmnt(masm_, "[ VariableProxy");
784 EmitVariableLoad(expr->var(), expr->context()); 784 EmitVariableLoad(expr->var(), context_);
785 } 785 }
786 786
787 787
788 void FastCodeGenerator::EmitVariableLoad(Variable* var, 788 void FastCodeGenerator::EmitVariableLoad(Variable* var,
789 Expression::Context context) { 789 Expression::Context context) {
790 Expression* rewrite = var->rewrite(); 790 Expression* rewrite = var->rewrite();
791 if (rewrite == NULL) { 791 if (rewrite == NULL) {
792 ASSERT(var->is_global()); 792 ASSERT(var->is_global());
793 Comment cmnt(masm_, "Global variable"); 793 Comment cmnt(masm_, "Global variable");
794 // Use inline caching. Variable name is passed in ecx and the global 794 // Use inline caching. Variable name is passed in ecx and the global
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 __ j(not_equal, &done); 878 __ j(not_equal, &done);
879 // Create regexp literal using runtime function 879 // Create regexp literal using runtime function
880 // Result will be in eax. 880 // Result will be in eax.
881 __ push(ebx); 881 __ push(ebx);
882 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 882 __ push(Immediate(Smi::FromInt(expr->literal_index())));
883 __ push(Immediate(expr->pattern())); 883 __ push(Immediate(expr->pattern()));
884 __ push(Immediate(expr->flags())); 884 __ push(Immediate(expr->flags()));
885 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 885 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
886 // Label done: 886 // Label done:
887 __ bind(&done); 887 __ bind(&done);
888 Apply(expr->context(), eax); 888 Apply(context_, eax);
889 } 889 }
890 890
891 891
892 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 892 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
893 Comment cmnt(masm_, "[ ObjectLiteral"); 893 Comment cmnt(masm_, "[ ObjectLiteral");
894 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 894 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
895 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); 895 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset));
896 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 896 __ push(Immediate(Smi::FromInt(expr->literal_index())));
897 __ push(Immediate(expr->constant_properties())); 897 __ push(Immediate(expr->constant_properties()));
898 if (expr->depth() > 1) { 898 if (expr->depth() > 1) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 Smi::FromInt(1) : 944 Smi::FromInt(1) :
945 Smi::FromInt(0))); 945 Smi::FromInt(0)));
946 VisitForValue(value, kStack); 946 VisitForValue(value, kStack);
947 __ CallRuntime(Runtime::kDefineAccessor, 4); 947 __ CallRuntime(Runtime::kDefineAccessor, 4);
948 break; 948 break;
949 default: UNREACHABLE(); 949 default: UNREACHABLE();
950 } 950 }
951 } 951 }
952 952
953 if (result_saved) { 953 if (result_saved) {
954 ApplyTOS(expr->context()); 954 ApplyTOS(context_);
955 } else { 955 } else {
956 Apply(expr->context(), eax); 956 Apply(context_, eax);
957 } 957 }
958 } 958 }
959 959
960 960
961 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 961 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
962 Comment cmnt(masm_, "[ ArrayLiteral"); 962 Comment cmnt(masm_, "[ ArrayLiteral");
963 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 963 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
964 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); 964 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
965 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 965 __ push(Immediate(Smi::FromInt(expr->literal_index())));
966 __ push(Immediate(expr->constant_elements())); 966 __ push(Immediate(expr->constant_elements()));
(...skipping 27 matching lines...) Expand all
994 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 994 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
995 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 995 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
996 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 996 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
997 __ mov(FieldOperand(ebx, offset), result_register()); 997 __ mov(FieldOperand(ebx, offset), result_register());
998 998
999 // Update the write barrier for the array store. 999 // Update the write barrier for the array store.
1000 __ RecordWrite(ebx, offset, result_register(), ecx); 1000 __ RecordWrite(ebx, offset, result_register(), ecx);
1001 } 1001 }
1002 1002
1003 if (result_saved) { 1003 if (result_saved) {
1004 ApplyTOS(expr->context()); 1004 ApplyTOS(context_);
1005 } else { 1005 } else {
1006 Apply(expr->context(), eax); 1006 Apply(context_, eax);
1007 } 1007 }
1008 } 1008 }
1009 1009
1010 1010
1011 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1011 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1012 SetSourcePosition(prop->position()); 1012 SetSourcePosition(prop->position());
1013 Literal* key = prop->key()->AsLiteral(); 1013 Literal* key = prop->key()->AsLiteral();
1014 __ mov(ecx, Immediate(key->handle())); 1014 __ mov(ecx, Immediate(key->handle()));
1015 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1015 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1016 __ call(ic, RelocInfo::CODE_TARGET); 1016 __ call(ic, RelocInfo::CODE_TARGET);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 __ nop(); 1110 __ nop();
1111 1111
1112 // If the assignment ends an initialization block, revert to fast case. 1112 // If the assignment ends an initialization block, revert to fast case.
1113 if (expr->ends_initialization_block()) { 1113 if (expr->ends_initialization_block()) {
1114 __ push(eax); // Result of assignment, saved even if not needed. 1114 __ push(eax); // Result of assignment, saved even if not needed.
1115 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1115 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1116 __ CallRuntime(Runtime::kToFastProperties, 1); 1116 __ CallRuntime(Runtime::kToFastProperties, 1);
1117 __ pop(eax); 1117 __ pop(eax);
1118 } 1118 }
1119 1119
1120 DropAndApply(1, expr->context(), eax); 1120 DropAndApply(1, context_, eax);
1121 } 1121 }
1122 1122
1123 1123
1124 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1124 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1125 // Assignment to a property, using a keyed store IC. 1125 // Assignment to a property, using a keyed store IC.
1126 1126
1127 // If the assignment starts a block of assignments to the same object, 1127 // If the assignment starts a block of assignments to the same object,
1128 // change to slow case to avoid the quadratic behavior of repeatedly 1128 // change to slow case to avoid the quadratic behavior of repeatedly
1129 // adding fast properties. 1129 // adding fast properties.
1130 if (expr->starts_initialization_block()) { 1130 if (expr->starts_initialization_block()) {
(...skipping 15 matching lines...) Expand all
1146 // If the assignment ends an initialization block, revert to fast case. 1146 // If the assignment ends an initialization block, revert to fast case.
1147 if (expr->ends_initialization_block()) { 1147 if (expr->ends_initialization_block()) {
1148 __ push(eax); // Result of assignment, saved even if not needed. 1148 __ push(eax); // Result of assignment, saved even if not needed.
1149 // Receiver is under the key and value. 1149 // Receiver is under the key and value.
1150 __ push(Operand(esp, 2 * kPointerSize)); 1150 __ push(Operand(esp, 2 * kPointerSize));
1151 __ CallRuntime(Runtime::kToFastProperties, 1); 1151 __ CallRuntime(Runtime::kToFastProperties, 1);
1152 __ pop(eax); 1152 __ pop(eax);
1153 } 1153 }
1154 1154
1155 // Receiver and key are still on stack. 1155 // Receiver and key are still on stack.
1156 DropAndApply(2, expr->context(), eax); 1156 DropAndApply(2, context_, eax);
1157 } 1157 }
1158 1158
1159 1159
1160 void FastCodeGenerator::VisitProperty(Property* expr) { 1160 void FastCodeGenerator::VisitProperty(Property* expr) {
1161 Comment cmnt(masm_, "[ Property"); 1161 Comment cmnt(masm_, "[ Property");
1162 Expression* key = expr->key(); 1162 Expression* key = expr->key();
1163 1163
1164 // Evaluate the receiver. 1164 // Evaluate the receiver.
1165 VisitForValue(expr->obj(), kStack); 1165 VisitForValue(expr->obj(), kStack);
1166 1166
1167 if (key->IsPropertyName()) { 1167 if (key->IsPropertyName()) {
1168 EmitNamedPropertyLoad(expr); 1168 EmitNamedPropertyLoad(expr);
1169 // Drop receiver left on the stack by IC. 1169 // Drop receiver left on the stack by IC.
1170 DropAndApply(1, expr->context(), eax); 1170 DropAndApply(1, context_, eax);
1171 } else { 1171 } else {
1172 VisitForValue(expr->key(), kStack); 1172 VisitForValue(expr->key(), kStack);
1173 EmitKeyedPropertyLoad(expr); 1173 EmitKeyedPropertyLoad(expr);
1174 // Drop key and receiver left on the stack by IC. 1174 // Drop key and receiver left on the stack by IC.
1175 DropAndApply(2, expr->context(), eax); 1175 DropAndApply(2, context_, eax);
1176 } 1176 }
1177 } 1177 }
1178 1178
1179 1179
1180 void FastCodeGenerator::EmitCallWithIC(Call* expr, 1180 void FastCodeGenerator::EmitCallWithIC(Call* expr,
1181 Handle<Object> name, 1181 Handle<Object> name,
1182 RelocInfo::Mode mode) { 1182 RelocInfo::Mode mode) {
1183 // Code common for calls using the IC. 1183 // Code common for calls using the IC.
1184 ZoneList<Expression*>* args = expr->arguments(); 1184 ZoneList<Expression*>* args = expr->arguments();
1185 int arg_count = args->length(); 1185 int arg_count = args->length();
1186 for (int i = 0; i < arg_count; i++) { 1186 for (int i = 0; i < arg_count; i++) {
1187 VisitForValue(args->at(i), kStack); 1187 VisitForValue(args->at(i), kStack);
1188 } 1188 }
1189 __ Set(ecx, Immediate(name)); 1189 __ Set(ecx, Immediate(name));
1190 // Record source position of the IC call. 1190 // Record source position of the IC call.
1191 SetSourcePosition(expr->position()); 1191 SetSourcePosition(expr->position());
1192 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1192 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1193 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 1193 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1194 __ call(ic, mode); 1194 __ call(ic, mode);
1195 // Restore context register. 1195 // Restore context register.
1196 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1196 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1197 Apply(expr->context(), eax); 1197 Apply(context_, eax);
1198 } 1198 }
1199 1199
1200 1200
1201 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1201 void FastCodeGenerator::EmitCallWithStub(Call* expr) {
1202 // Code common for calls using the call stub. 1202 // Code common for calls using the call stub.
1203 ZoneList<Expression*>* args = expr->arguments(); 1203 ZoneList<Expression*>* args = expr->arguments();
1204 int arg_count = args->length(); 1204 int arg_count = args->length();
1205 for (int i = 0; i < arg_count; i++) { 1205 for (int i = 0; i < arg_count; i++) {
1206 VisitForValue(args->at(i), kStack); 1206 VisitForValue(args->at(i), kStack);
1207 } 1207 }
1208 // Record source position for debugger. 1208 // Record source position for debugger.
1209 SetSourcePosition(expr->position()); 1209 SetSourcePosition(expr->position());
1210 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); 1210 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
1211 __ CallStub(&stub); 1211 __ CallStub(&stub);
1212 // Restore context register. 1212 // Restore context register.
1213 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1213 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1214 DropAndApply(1, expr->context(), eax); 1214 DropAndApply(1, context_, eax);
1215 } 1215 }
1216 1216
1217 1217
1218 void FastCodeGenerator::VisitCall(Call* expr) { 1218 void FastCodeGenerator::VisitCall(Call* expr) {
1219 Comment cmnt(masm_, "[ Call"); 1219 Comment cmnt(masm_, "[ Call");
1220 Expression* fun = expr->expression(); 1220 Expression* fun = expr->expression();
1221 Variable* var = fun->AsVariableProxy()->AsVariable(); 1221 Variable* var = fun->AsVariableProxy()->AsVariable();
1222 1222
1223 if (var != NULL && var->is_possibly_eval()) { 1223 if (var != NULL && var->is_possibly_eval()) {
1224 // Call to the identifier 'eval'. 1224 // Call to the identifier 'eval'.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 1310
1311 // Load function, arg_count into edi and eax. 1311 // Load function, arg_count into edi and eax.
1312 __ Set(eax, Immediate(arg_count)); 1312 __ Set(eax, Immediate(arg_count));
1313 // Function is in esp[arg_count + 1]. 1313 // Function is in esp[arg_count + 1].
1314 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize)); 1314 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1315 1315
1316 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1316 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1317 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1317 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1318 1318
1319 // Replace function on TOS with result in eax, or pop it. 1319 // Replace function on TOS with result in eax, or pop it.
1320 DropAndApply(1, expr->context(), eax); 1320 DropAndApply(1, context_, eax);
1321 } 1321 }
1322 1322
1323 1323
1324 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1324 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1325 Comment cmnt(masm_, "[ CallRuntime"); 1325 Comment cmnt(masm_, "[ CallRuntime");
1326 ZoneList<Expression*>* args = expr->arguments(); 1326 ZoneList<Expression*>* args = expr->arguments();
1327 1327
1328 if (expr->is_jsruntime()) { 1328 if (expr->is_jsruntime()) {
1329 // Prepare for calling JS runtime function. 1329 // Prepare for calling JS runtime function.
1330 __ mov(eax, CodeGenerator::GlobalObject()); 1330 __ mov(eax, CodeGenerator::GlobalObject());
(...skipping 11 matching lines...) Expand all
1342 __ Set(ecx, Immediate(expr->name())); 1342 __ Set(ecx, Immediate(expr->name()));
1343 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1343 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1344 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 1344 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1345 __ call(ic, RelocInfo::CODE_TARGET); 1345 __ call(ic, RelocInfo::CODE_TARGET);
1346 // Restore context register. 1346 // Restore context register.
1347 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1347 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1348 } else { 1348 } else {
1349 // Call the C runtime function. 1349 // Call the C runtime function.
1350 __ CallRuntime(expr->function(), arg_count); 1350 __ CallRuntime(expr->function(), arg_count);
1351 } 1351 }
1352 Apply(expr->context(), eax); 1352 Apply(context_, eax);
1353 } 1353 }
1354 1354
1355 1355
1356 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 1356 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1357 switch (expr->op()) { 1357 switch (expr->op()) {
1358 case Token::VOID: { 1358 case Token::VOID: {
1359 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 1359 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1360 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); 1360 VisitForEffect(expr->expression());
1361 Visit(expr->expression()); 1361 switch (context_) {
1362 switch (expr->context()) {
1363 case Expression::kUninitialized: 1362 case Expression::kUninitialized:
1364 UNREACHABLE(); 1363 UNREACHABLE();
1365 break; 1364 break;
1366 case Expression::kEffect: 1365 case Expression::kEffect:
1367 break; 1366 break;
1368 case Expression::kValue: 1367 case Expression::kValue:
1369 switch (location_) { 1368 switch (location_) {
1370 case kAccumulator: 1369 case kAccumulator:
1371 __ mov(result_register(), Factory::undefined_value()); 1370 __ mov(result_register(), Factory::undefined_value());
1372 break; 1371 break;
(...skipping 16 matching lines...) Expand all
1389 case Expression::kTest: 1388 case Expression::kTest:
1390 case Expression::kValueTest: 1389 case Expression::kValueTest:
1391 __ jmp(false_label_); 1390 __ jmp(false_label_);
1392 break; 1391 break;
1393 } 1392 }
1394 break; 1393 break;
1395 } 1394 }
1396 1395
1397 case Token::NOT: { 1396 case Token::NOT: {
1398 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 1397 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
1399 ASSERT_EQ(Expression::kTest, expr->expression()->context());
1400
1401 Label materialize_true, materialize_false, done; 1398 Label materialize_true, materialize_false, done;
1402 // Initially assume a pure test context. Notice that the labels are 1399 // Initially assume a pure test context. Notice that the labels are
1403 // swapped. 1400 // swapped.
1404 Label* if_true = false_label_; 1401 Label* if_true = false_label_;
1405 Label* if_false = true_label_; 1402 Label* if_false = true_label_;
1406 switch (expr->context()) { 1403 switch (context_) {
1407 case Expression::kUninitialized: 1404 case Expression::kUninitialized:
1408 UNREACHABLE(); 1405 UNREACHABLE();
1409 break; 1406 break;
1410 case Expression::kEffect: 1407 case Expression::kEffect:
1411 if_true = &done; 1408 if_true = &done;
1412 if_false = &done; 1409 if_false = &done;
1413 break; 1410 break;
1414 case Expression::kValue: 1411 case Expression::kValue:
1415 if_true = &materialize_false; 1412 if_true = &materialize_false;
1416 if_false = &materialize_true; 1413 if_false = &materialize_true;
1417 break; 1414 break;
1418 case Expression::kTest: 1415 case Expression::kTest:
1419 break; 1416 break;
1420 case Expression::kValueTest: 1417 case Expression::kValueTest:
1421 if_false = &materialize_true; 1418 if_false = &materialize_true;
1422 break; 1419 break;
1423 case Expression::kTestValue: 1420 case Expression::kTestValue:
1424 if_true = &materialize_false; 1421 if_true = &materialize_false;
1425 break; 1422 break;
1426 } 1423 }
1427 VisitForControl(expr->expression(), if_true, if_false); 1424 VisitForControl(expr->expression(), if_true, if_false);
1428 Apply(expr->context(), if_false, if_true); // Labels swapped. 1425 Apply(context_, if_false, if_true); // Labels swapped.
1429 break; 1426 break;
1430 } 1427 }
1431 1428
1432 case Token::TYPEOF: { 1429 case Token::TYPEOF: {
1433 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 1430 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
1434 ASSERT_EQ(Expression::kValue, expr->expression()->context());
1435
1436 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 1431 VariableProxy* proxy = expr->expression()->AsVariableProxy();
1437 if (proxy != NULL && 1432 if (proxy != NULL &&
1438 !proxy->var()->is_this() && 1433 !proxy->var()->is_this() &&
1439 proxy->var()->is_global()) { 1434 proxy->var()->is_global()) {
1440 Comment cmnt(masm_, "Global variable"); 1435 Comment cmnt(masm_, "Global variable");
1441 __ push(CodeGenerator::GlobalObject()); 1436 __ push(CodeGenerator::GlobalObject());
1442 __ mov(ecx, Immediate(proxy->name())); 1437 __ mov(ecx, Immediate(proxy->name()));
1443 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1438 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1444 // Use a regular load, not a contextual load, to avoid a reference 1439 // Use a regular load, not a contextual load, to avoid a reference
1445 // error. 1440 // error.
1446 __ call(ic, RelocInfo::CODE_TARGET); 1441 __ call(ic, RelocInfo::CODE_TARGET);
1447 __ mov(Operand(esp, 0), eax); 1442 __ mov(Operand(esp, 0), eax);
1448 } else if (proxy != NULL && 1443 } else if (proxy != NULL &&
1449 proxy->var()->slot() != NULL && 1444 proxy->var()->slot() != NULL &&
1450 proxy->var()->slot()->type() == Slot::LOOKUP) { 1445 proxy->var()->slot()->type() == Slot::LOOKUP) {
1451 __ push(esi); 1446 __ push(esi);
1452 __ push(Immediate(proxy->name())); 1447 __ push(Immediate(proxy->name()));
1453 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 1448 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
1454 __ push(eax); 1449 __ push(eax);
1455 } else { 1450 } else {
1456 // This expression cannot throw a reference error at the top level. 1451 // This expression cannot throw a reference error at the top level.
1457 VisitForValue(expr->expression(), kStack); 1452 VisitForValue(expr->expression(), kStack);
1458 } 1453 }
1459 1454
1460 __ CallRuntime(Runtime::kTypeof, 1); 1455 __ CallRuntime(Runtime::kTypeof, 1);
1461 Apply(expr->context(), eax); 1456 Apply(context_, eax);
1462 break; 1457 break;
1463 } 1458 }
1464 1459
1465 default: 1460 default:
1466 UNREACHABLE(); 1461 UNREACHABLE();
1467 } 1462 }
1468 } 1463 }
1469 1464
1470 1465
1471 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 1466 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
1472 Comment cmnt(masm_, "[ CountOperation"); 1467 Comment cmnt(masm_, "[ CountOperation");
1473 1468
1474 // Expression can only be a property, a global or a (parameter or local) 1469 // Expression can only be a property, a global or a (parameter or local)
1475 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1470 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
1476 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1471 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1477 LhsKind assign_type = VARIABLE; 1472 LhsKind assign_type = VARIABLE;
1478 Property* prop = expr->expression()->AsProperty(); 1473 Property* prop = expr->expression()->AsProperty();
1479 // In case of a property we use the uninitialized expression context 1474 // In case of a property we use the uninitialized expression context
1480 // of the key to detect a named property. 1475 // of the key to detect a named property.
1481 if (prop != NULL) { 1476 if (prop != NULL) {
1482 assign_type = (prop->key()->context() == Expression::kUninitialized) 1477 assign_type =
1483 ? NAMED_PROPERTY 1478 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
1484 : KEYED_PROPERTY;
1485 } 1479 }
1486 1480
1487 // Evaluate expression and get value. 1481 // Evaluate expression and get value.
1488 if (assign_type == VARIABLE) { 1482 if (assign_type == VARIABLE) {
1489 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 1483 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
1490 Location saved_location = location_; 1484 Location saved_location = location_;
1491 location_ = kStack; 1485 location_ = kStack;
1492 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), 1486 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(),
1493 Expression::kValue); 1487 Expression::kValue);
1494 location_ = saved_location; 1488 location_ = saved_location;
1495 } else { 1489 } else {
1496 // Reserve space for result of postfix operation. 1490 // Reserve space for result of postfix operation.
1497 if (expr->is_postfix() && expr->context() != Expression::kEffect) { 1491 if (expr->is_postfix() && context_ != Expression::kEffect) {
1498 ASSERT(expr->context() != Expression::kUninitialized);
1499 __ push(Immediate(Smi::FromInt(0))); 1492 __ push(Immediate(Smi::FromInt(0)));
1500 } 1493 }
1501 VisitForValue(prop->obj(), kStack); 1494 VisitForValue(prop->obj(), kStack);
1502 if (assign_type == NAMED_PROPERTY) { 1495 if (assign_type == NAMED_PROPERTY) {
1503 EmitNamedPropertyLoad(prop); 1496 EmitNamedPropertyLoad(prop);
1504 } else { 1497 } else {
1505 VisitForValue(prop->key(), kStack); 1498 VisitForValue(prop->key(), kStack);
1506 EmitKeyedPropertyLoad(prop); 1499 EmitKeyedPropertyLoad(prop);
1507 } 1500 }
1508 __ push(eax); 1501 __ push(eax);
1509 } 1502 }
1510 1503
1511 // Convert to number. 1504 // Convert to number.
1512 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); 1505 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
1513 1506
1514 // Save result for postfix expressions. 1507 // Save result for postfix expressions.
1515 if (expr->is_postfix()) { 1508 if (expr->is_postfix()) {
1516 switch (expr->context()) { 1509 switch (context_) {
1517 case Expression::kUninitialized: 1510 case Expression::kUninitialized:
1518 UNREACHABLE(); 1511 UNREACHABLE();
1519 case Expression::kEffect: 1512 case Expression::kEffect:
1520 // Do not save result. 1513 // Do not save result.
1521 break; 1514 break;
1522 case Expression::kValue: 1515 case Expression::kValue:
1523 case Expression::kTest: 1516 case Expression::kTest:
1524 case Expression::kValueTest: 1517 case Expression::kValueTest:
1525 case Expression::kTestValue: 1518 case Expression::kTestValue:
1526 // Save the result on the stack. If we have a named or keyed property 1519 // Save the result on the stack. If we have a named or keyed property
(...skipping 23 matching lines...) Expand all
1550 __ CallStub(&stub); 1543 __ CallStub(&stub);
1551 1544
1552 // Store the value returned in eax. 1545 // Store the value returned in eax.
1553 switch (assign_type) { 1546 switch (assign_type) {
1554 case VARIABLE: 1547 case VARIABLE:
1555 if (expr->is_postfix()) { 1548 if (expr->is_postfix()) {
1556 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 1549 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
1557 Expression::kEffect); 1550 Expression::kEffect);
1558 // For all contexts except kEffect: We have the result on 1551 // For all contexts except kEffect: We have the result on
1559 // top of the stack. 1552 // top of the stack.
1560 if (expr->context() != Expression::kEffect) { 1553 if (context_ != Expression::kEffect) {
1561 ApplyTOS(expr->context()); 1554 ApplyTOS(context_);
1562 } 1555 }
1563 } else { 1556 } else {
1564 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 1557 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
1565 expr->context()); 1558 context_);
1566 } 1559 }
1567 break; 1560 break;
1568 case NAMED_PROPERTY: { 1561 case NAMED_PROPERTY: {
1569 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1562 __ mov(ecx, prop->key()->AsLiteral()->handle());
1570 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1563 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1571 __ call(ic, RelocInfo::CODE_TARGET); 1564 __ call(ic, RelocInfo::CODE_TARGET);
1572 // This nop signals to the IC that there is no inlined code at the call 1565 // This nop signals to the IC that there is no inlined code at the call
1573 // site for it to patch. 1566 // site for it to patch.
1574 __ nop(); 1567 __ nop();
1575 if (expr->is_postfix()) { 1568 if (expr->is_postfix()) {
1576 __ Drop(1); // Result is on the stack under the receiver. 1569 __ Drop(1); // Result is on the stack under the receiver.
1577 if (expr->context() != Expression::kEffect) { 1570 if (context_ != Expression::kEffect) {
1578 ApplyTOS(expr->context()); 1571 ApplyTOS(context_);
1579 } 1572 }
1580 } else { 1573 } else {
1581 DropAndApply(1, expr->context(), eax); 1574 DropAndApply(1, context_, eax);
1582 } 1575 }
1583 break; 1576 break;
1584 } 1577 }
1585 case KEYED_PROPERTY: { 1578 case KEYED_PROPERTY: {
1586 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1579 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1587 __ call(ic, RelocInfo::CODE_TARGET); 1580 __ call(ic, RelocInfo::CODE_TARGET);
1588 // This nop signals to the IC that there is no inlined code at the call 1581 // This nop signals to the IC that there is no inlined code at the call
1589 // site for it to patch. 1582 // site for it to patch.
1590 __ nop(); 1583 __ nop();
1591 if (expr->is_postfix()) { 1584 if (expr->is_postfix()) {
1592 __ Drop(2); // Result is on the stack under the key and the receiver. 1585 __ Drop(2); // Result is on the stack under the key and the receiver.
1593 if (expr->context() != Expression::kEffect) { 1586 if (context_ != Expression::kEffect) {
1594 ApplyTOS(expr->context()); 1587 ApplyTOS(context_);
1595 } 1588 }
1596 } else { 1589 } else {
1597 DropAndApply(2, expr->context(), eax); 1590 DropAndApply(2, context_, eax);
1598 } 1591 }
1599 break; 1592 break;
1600 } 1593 }
1601 } 1594 }
1602 } 1595 }
1603 1596
1604 1597
1605 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 1598 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
1606 Comment cmnt(masm_, "[ BinaryOperation"); 1599 Comment cmnt(masm_, "[ BinaryOperation");
1607 switch (expr->op()) { 1600 switch (expr->op()) {
1608 case Token::COMMA: 1601 case Token::COMMA:
1609 ASSERT_EQ(Expression::kEffect, expr->left()->context()); 1602 VisitForEffect(expr->left());
1610 ASSERT_EQ(expr->context(), expr->right()->context());
1611 Visit(expr->left());
1612 Visit(expr->right()); 1603 Visit(expr->right());
1613 break; 1604 break;
1614 1605
1615 case Token::OR: 1606 case Token::OR:
1616 case Token::AND: 1607 case Token::AND:
1617 EmitLogicalOperation(expr); 1608 EmitLogicalOperation(expr);
1618 break; 1609 break;
1619 1610
1620 case Token::ADD: 1611 case Token::ADD:
1621 case Token::SUB: 1612 case Token::SUB:
1622 case Token::DIV: 1613 case Token::DIV:
1623 case Token::MOD: 1614 case Token::MOD:
1624 case Token::MUL: 1615 case Token::MUL:
1625 case Token::BIT_OR: 1616 case Token::BIT_OR:
1626 case Token::BIT_AND: 1617 case Token::BIT_AND:
1627 case Token::BIT_XOR: 1618 case Token::BIT_XOR:
1628 case Token::SHL: 1619 case Token::SHL:
1629 case Token::SHR: 1620 case Token::SHR:
1630 case Token::SAR: 1621 case Token::SAR:
1631 VisitForValue(expr->left(), kStack); 1622 VisitForValue(expr->left(), kStack);
1632 VisitForValue(expr->right(), kAccumulator); 1623 VisitForValue(expr->right(), kAccumulator);
1633 EmitBinaryOp(expr->op(), expr->context()); 1624 EmitBinaryOp(expr->op(), context_);
1634 break; 1625 break;
1635 1626
1636 default: 1627 default:
1637 UNREACHABLE(); 1628 UNREACHABLE();
1638 } 1629 }
1639 } 1630 }
1640 1631
1641 1632
1642 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1633 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1643 Comment cmnt(masm_, "[ CompareOperation"); 1634 Comment cmnt(masm_, "[ CompareOperation");
1644 1635
1645 // Always perform the comparison for its control flow. Pack the result 1636 // Always perform the comparison for its control flow. Pack the result
1646 // into the expression's context after the comparison is performed. 1637 // into the expression's context after the comparison is performed.
1647 Label materialize_true, materialize_false, done; 1638 Label materialize_true, materialize_false, done;
1648 // Initially assume we are in a test context. 1639 // Initially assume we are in a test context.
1649 Label* if_true = true_label_; 1640 Label* if_true = true_label_;
1650 Label* if_false = false_label_; 1641 Label* if_false = false_label_;
1651 switch (expr->context()) { 1642 switch (context_) {
1652 case Expression::kUninitialized: 1643 case Expression::kUninitialized:
1653 UNREACHABLE(); 1644 UNREACHABLE();
1654 break; 1645 break;
1655 case Expression::kEffect: 1646 case Expression::kEffect:
1656 if_true = &done; 1647 if_true = &done;
1657 if_false = &done; 1648 if_false = &done;
1658 break; 1649 break;
1659 case Expression::kValue: 1650 case Expression::kValue:
1660 if_true = &materialize_true; 1651 if_true = &materialize_true;
1661 if_false = &materialize_false; 1652 if_false = &materialize_false;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 CompareStub stub(cc, strict); 1734 CompareStub stub(cc, strict);
1744 __ CallStub(&stub); 1735 __ CallStub(&stub);
1745 __ test(eax, Operand(eax)); 1736 __ test(eax, Operand(eax));
1746 __ j(cc, if_true); 1737 __ j(cc, if_true);
1747 __ jmp(if_false); 1738 __ jmp(if_false);
1748 } 1739 }
1749 } 1740 }
1750 1741
1751 // Convert the result of the comparison into one expected for this 1742 // Convert the result of the comparison into one expected for this
1752 // expression's context. 1743 // expression's context.
1753 Apply(expr->context(), if_true, if_false); 1744 Apply(context_, if_true, if_false);
1754 } 1745 }
1755 1746
1756 1747
1757 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1748 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1758 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1749 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1759 Apply(expr->context(), eax); 1750 Apply(context_, eax);
1760 } 1751 }
1761 1752
1762 1753
1763 Register FastCodeGenerator::result_register() { return eax; } 1754 Register FastCodeGenerator::result_register() { return eax; }
1764 1755
1765 1756
1766 Register FastCodeGenerator::context_register() { return esi; } 1757 Register FastCodeGenerator::context_register() { return esi; }
1767 1758
1768 1759
1769 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 1760 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 __ add(Operand(edx), Immediate(masm_->CodeObject())); 1795 __ add(Operand(edx), Immediate(masm_->CodeObject()));
1805 __ mov(Operand(esp, 0), edx); 1796 __ mov(Operand(esp, 0), edx);
1806 // And return. 1797 // And return.
1807 __ ret(0); 1798 __ ret(0);
1808 } 1799 }
1809 1800
1810 1801
1811 #undef __ 1802 #undef __
1812 1803
1813 } } // namespace v8::internal 1804 } } // namespace v8::internal
OLDNEW
« src/compiler.cc ('K') | « src/fast-codegen.cc ('k') | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698