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

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

Issue 550043: Fix issue 541 and some refactoring of the top-level compiler. (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
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 125 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
126 __ CallStub(&stub); 126 __ CallStub(&stub);
127 // Store new arguments object in both "arguments" and ".arguments" slots. 127 // Store new arguments object in both "arguments" and ".arguments" slots.
128 __ movq(rcx, rax); 128 __ movq(rcx, rax);
129 Move(arguments->slot(), rax, rbx, rdx); 129 Move(arguments->slot(), rax, rbx, rdx);
130 Slot* dot_arguments_slot = 130 Slot* dot_arguments_slot =
131 fun->scope()->arguments_shadow()->AsVariable()->slot(); 131 fun->scope()->arguments_shadow()->AsVariable()->slot();
132 Move(dot_arguments_slot, rcx, rbx, rdx); 132 Move(dot_arguments_slot, rcx, rbx, rdx);
133 } 133 }
134 134
135 { Comment cmnt(masm_, "[ Declarations");
136 VisitDeclarations(fun->scope()->declarations());
137 }
138
135 { Comment cmnt(masm_, "[ Stack check"); 139 { Comment cmnt(masm_, "[ Stack check");
136 Label ok; 140 Label ok;
137 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 141 __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
138 __ j(above_equal, &ok); 142 __ j(above_equal, &ok);
139 StackCheckStub stub; 143 StackCheckStub stub;
140 __ CallStub(&stub); 144 __ CallStub(&stub);
141 __ bind(&ok); 145 __ bind(&ok);
142 } 146 }
143 147
144 { Comment cmnt(masm_, "[ Declarations");
145 VisitDeclarations(fun->scope()->declarations());
146 }
147
148 if (FLAG_trace) { 148 if (FLAG_trace) {
149 __ CallRuntime(Runtime::kTraceEnter, 0); 149 __ CallRuntime(Runtime::kTraceEnter, 0);
150 } 150 }
151 151
152 { Comment cmnt(masm_, "[ Body"); 152 { Comment cmnt(masm_, "[ Body");
153 ASSERT(loop_depth() == 0); 153 ASSERT(loop_depth() == 0);
154 VisitStatements(fun->body()); 154 VisitStatements(fun->body());
155 ASSERT(loop_depth() == 0); 155 ASSERT(loop_depth() == 0);
156 } 156 }
157 157
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 TestAndBranch(rax, &discard, false_label_); 810 TestAndBranch(rax, &discard, false_label_);
811 __ bind(&discard); 811 __ bind(&discard);
812 __ Drop(1); 812 __ Drop(1);
813 __ jmp(true_label_); 813 __ jmp(true_label_);
814 break; 814 break;
815 } 815 }
816 } 816 }
817 } 817 }
818 818
819 819
820 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop, 820 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
821 Expression::Context context) {
822 SetSourcePosition(prop->position()); 821 SetSourcePosition(prop->position());
823 Literal* key = prop->key()->AsLiteral(); 822 Literal* key = prop->key()->AsLiteral();
824 __ Move(rcx, key->handle()); 823 __ Move(rcx, key->handle());
825 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 824 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
826 __ Call(ic, RelocInfo::CODE_TARGET); 825 __ Call(ic, RelocInfo::CODE_TARGET);
827 Apply(context, rax); 826 __ nop();
828 } 827 }
829 828
830 829
831 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop, 830 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
832 Expression::Context context) {
833 SetSourcePosition(prop->position()); 831 SetSourcePosition(prop->position());
834 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 832 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
835 __ Call(ic, RelocInfo::CODE_TARGET); 833 __ Call(ic, RelocInfo::CODE_TARGET);
836 Apply(context, rax); 834 __ nop();
837 } 835 }
838 836
839 837
840 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, 838 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op,
841 Expression::Context context) { 839 Expression::Context context) {
842 GenericBinaryOpStub stub(op, 840 GenericBinaryOpStub stub(op,
843 NO_OVERWRITE, 841 NO_OVERWRITE,
844 NO_GENERIC_BINARY_FLAGS); 842 NO_GENERIC_BINARY_FLAGS);
845 __ CallStub(&stub); 843 __ CallStub(&stub);
846 Apply(context, rax); 844 Apply(context, rax);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 ASSERT(prop->key()->AsLiteral() != NULL); 947 ASSERT(prop->key()->AsLiteral() != NULL);
950 948
951 // If the assignment starts a block of assignments to the same object, 949 // If the assignment starts a block of assignments to the same object,
952 // change to slow case to avoid the quadratic behavior of repeatedly 950 // change to slow case to avoid the quadratic behavior of repeatedly
953 // adding fast properties. 951 // adding fast properties.
954 if (expr->starts_initialization_block()) { 952 if (expr->starts_initialization_block()) {
955 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 953 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
956 __ CallRuntime(Runtime::kToSlowProperties, 1); 954 __ CallRuntime(Runtime::kToSlowProperties, 1);
957 } 955 }
958 956
957 // Record source code position before IC call.
958 SetSourcePosition(expr->position());
959
959 __ pop(rax); 960 __ pop(rax);
960 __ Move(rcx, prop->key()->AsLiteral()->handle()); 961 __ Move(rcx, prop->key()->AsLiteral()->handle());
961 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 962 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
962 __ Call(ic, RelocInfo::CODE_TARGET); 963 __ Call(ic, RelocInfo::CODE_TARGET);
963 964
964 // If the assignment ends an initialization block, revert to fast case. 965 // If the assignment ends an initialization block, revert to fast case.
965 if (expr->ends_initialization_block()) { 966 if (expr->ends_initialization_block()) {
966 __ push(rax); // Result of assignment, saved even if not needed. 967 __ push(rax); // Result of assignment, saved even if not needed.
967 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 968 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
968 __ CallRuntime(Runtime::kToFastProperties, 1); 969 __ CallRuntime(Runtime::kToFastProperties, 1);
969 __ pop(rax); 970 __ pop(rax);
970 } 971 }
971 972
972 DropAndApply(1, expr->context(), rax); 973 DropAndApply(1, expr->context(), rax);
973 } 974 }
974 975
975 976
976 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 977 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
977 // Assignment to a property, using a keyed store IC. 978 // Assignment to a property, using a keyed store IC.
978 979
979 // If the assignment starts a block of assignments to the same object, 980 // If the assignment starts a block of assignments to the same object,
980 // change to slow case to avoid the quadratic behavior of repeatedly 981 // change to slow case to avoid the quadratic behavior of repeatedly
981 // adding fast properties. 982 // adding fast properties.
982 if (expr->starts_initialization_block()) { 983 if (expr->starts_initialization_block()) {
983 // Reciever is under the key and value. 984 // Reciever is under the key and value.
984 __ push(Operand(rsp, 2 * kPointerSize)); 985 __ push(Operand(rsp, 2 * kPointerSize));
985 __ CallRuntime(Runtime::kToSlowProperties, 1); 986 __ CallRuntime(Runtime::kToSlowProperties, 1);
986 } 987 }
987 988
989 // Record source code position before IC call.
990 SetSourcePosition(expr->position());
991
988 __ pop(rax); 992 __ pop(rax);
989 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 993 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
990 __ Call(ic, RelocInfo::CODE_TARGET); 994 __ Call(ic, RelocInfo::CODE_TARGET);
991 // This nop signals to the IC that there is no inlined code at the call 995 // This nop signals to the IC that there is no inlined code at the call
992 // site for it to patch. 996 // site for it to patch.
993 __ nop(); 997 __ nop();
994 998
995 // If the assignment ends an initialization block, revert to fast case. 999 // If the assignment ends an initialization block, revert to fast case.
996 if (expr->ends_initialization_block()) { 1000 if (expr->ends_initialization_block()) {
997 __ push(rax); // Result of assignment, saved even if not needed. 1001 __ push(rax); // Result of assignment, saved even if not needed.
998 // Reciever is under the key and value. 1002 // Reciever is under the key and value.
999 __ push(Operand(rsp, 2 * kPointerSize)); 1003 __ push(Operand(rsp, 2 * kPointerSize));
1000 __ CallRuntime(Runtime::kToFastProperties, 1); 1004 __ CallRuntime(Runtime::kToFastProperties, 1);
1001 __ pop(rax); 1005 __ pop(rax);
1002 } 1006 }
1003 1007
1004 // Receiver and key are still on stack. 1008 // Receiver and key are still on stack.
1005 DropAndApply(2, expr->context(), rax); 1009 DropAndApply(2, expr->context(), rax);
1006 } 1010 }
1007 1011
1008 1012
1009 void FastCodeGenerator::VisitProperty(Property* expr) { 1013 void FastCodeGenerator::VisitProperty(Property* expr) {
1010 Comment cmnt(masm_, "[ Property"); 1014 Comment cmnt(masm_, "[ Property");
1011 Expression* key = expr->key(); 1015 Expression* key = expr->key();
1012 1016
1013 // Record the source position for the property load.
1014 SetSourcePosition(expr->position());
1015
1016 // Evaluate receiver. 1017 // Evaluate receiver.
1017 Visit(expr->obj()); 1018 Visit(expr->obj());
1018 1019
1019 if (key->IsPropertyName()) { 1020 if (key->IsPropertyName()) {
1020 // Do a named property load. The IC expects the property name in rcx 1021 EmitNamedPropertyLoad(expr);
1021 // and the receiver on the stack. 1022 // Drop receiver left on the stack by IC.
1022 __ Move(rcx, key->AsLiteral()->handle());
1023 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1024 __ call(ic, RelocInfo::CODE_TARGET);
1025 // By emitting a nop we make sure that we do not have a "test rax,..."
1026 // instruction after the call it is treated specially by the LoadIC code.
1027 __ nop();
1028 DropAndApply(1, expr->context(), rax); 1023 DropAndApply(1, expr->context(), rax);
1029 } else { 1024 } else {
1030 // Do a keyed property load.
1031 Visit(expr->key()); 1025 Visit(expr->key());
1032 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1026 EmitKeyedPropertyLoad(expr);
1033 __ call(ic, RelocInfo::CODE_TARGET);
1034 // Notice: We must not have a "test rax, ..." instruction after the
1035 // call. It is treated specially by the LoadIC code.
1036 __ nop();
1037 // Drop key and receiver left on the stack by IC. 1027 // Drop key and receiver left on the stack by IC.
1038 DropAndApply(2, expr->context(), rax); 1028 DropAndApply(2, expr->context(), rax);
1039 } 1029 }
1040 } 1030 }
1041 1031
1042 1032
1043 void FastCodeGenerator::EmitCallWithIC(Call* expr, 1033 void FastCodeGenerator::EmitCallWithIC(Call* expr,
1044 Handle<Object> ignored, 1034 Handle<Object> ignored,
1045 RelocInfo::Mode mode) { 1035 RelocInfo::Mode mode) {
1046 // Code common for calls using the IC. 1036 // Code common for calls using the IC.
1047 ZoneList<Expression*>* args = expr->arguments(); 1037 ZoneList<Expression*>* args = expr->arguments();
1048 int arg_count = args->length(); 1038 int arg_count = args->length();
1049 for (int i = 0; i < arg_count; i++) { 1039 for (int i = 0; i < arg_count; i++) {
1050 Visit(args->at(i)); 1040 Visit(args->at(i));
1051 ASSERT_EQ(Expression::kValue, args->at(i)->context()); 1041 ASSERT_EQ(Expression::kValue, args->at(i)->context());
1052 } 1042 }
1053 // Record source position for debugger. 1043 // Record source position for debugger.
1054 SetSourcePosition(expr->position()); 1044 SetSourcePosition(expr->position());
1055 // Call the IC initialization code. 1045 // Call the IC initialization code.
1046 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1056 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1047 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1057 NOT_IN_LOOP); 1048 in_loop);
1058 __ call(ic, mode); 1049 __ Call(ic, mode);
1059 // Restore context register. 1050 // Restore context register.
1060 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1051 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1061 // Discard the function left on TOS. 1052 // Discard the function left on TOS.
1062 DropAndApply(1, expr->context(), rax); 1053 DropAndApply(1, expr->context(), rax);
1063 } 1054 }
1064 1055
1065 1056
1066 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1057 void FastCodeGenerator::EmitCallWithStub(Call* expr) {
1067 // Code common for calls using the call stub. 1058 // Code common for calls using the call stub.
1068 ZoneList<Expression*>* args = expr->arguments(); 1059 ZoneList<Expression*>* args = expr->arguments();
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 Expression::kValue); 1355 Expression::kValue);
1365 } else { 1356 } else {
1366 // Reserve space for result of postfix operation. 1357 // Reserve space for result of postfix operation.
1367 if (expr->is_postfix() && expr->context() != Expression::kEffect) { 1358 if (expr->is_postfix() && expr->context() != Expression::kEffect) {
1368 ASSERT(expr->context() != Expression::kUninitialized); 1359 ASSERT(expr->context() != Expression::kUninitialized);
1369 __ Push(Smi::FromInt(0)); 1360 __ Push(Smi::FromInt(0));
1370 } 1361 }
1371 Visit(prop->obj()); 1362 Visit(prop->obj());
1372 ASSERT_EQ(Expression::kValue, prop->obj()->context()); 1363 ASSERT_EQ(Expression::kValue, prop->obj()->context());
1373 if (assign_type == NAMED_PROPERTY) { 1364 if (assign_type == NAMED_PROPERTY) {
1374 EmitNamedPropertyLoad(prop, Expression::kValue); 1365 EmitNamedPropertyLoad(prop);
1375 } else { 1366 } else {
1376 Visit(prop->key()); 1367 Visit(prop->key());
1377 ASSERT_EQ(Expression::kValue, prop->key()->context()); 1368 ASSERT_EQ(Expression::kValue, prop->key()->context());
1378 EmitKeyedPropertyLoad(prop, Expression::kValue); 1369 EmitKeyedPropertyLoad(prop);
1379 } 1370 }
1371 __ push(rax);
1380 } 1372 }
1381 1373
1382 // Convert to number. 1374 // Convert to number.
1383 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); 1375 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
1384 1376
1385 // Save result for postfix expressions. 1377 // Save result for postfix expressions.
1386 if (expr->is_postfix()) { 1378 if (expr->is_postfix()) {
1387 switch (expr->context()) { 1379 switch (expr->context()) {
1388 case Expression::kUninitialized: 1380 case Expression::kUninitialized:
1389 UNREACHABLE(); 1381 UNREACHABLE();
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 __ movq(Operand(rsp, 0), rdx); 1712 __ movq(Operand(rsp, 0), rdx);
1721 // And return. 1713 // And return.
1722 __ ret(0); 1714 __ ret(0);
1723 } 1715 }
1724 1716
1725 1717
1726 #undef __ 1718 #undef __
1727 1719
1728 1720
1729 } } // namespace v8::internal 1721 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698