OLD | NEW |
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 { Comment cmnt(masm_, "[ Declarations"); | 78 { Comment cmnt(masm_, "[ Declarations"); |
79 VisitDeclarations(fun->scope()->declarations()); | 79 VisitDeclarations(fun->scope()->declarations()); |
80 } | 80 } |
81 | 81 |
82 if (FLAG_trace) { | 82 if (FLAG_trace) { |
83 __ CallRuntime(Runtime::kTraceEnter, 0); | 83 __ CallRuntime(Runtime::kTraceEnter, 0); |
84 } | 84 } |
85 | 85 |
86 { Comment cmnt(masm_, "[ Body"); | 86 { Comment cmnt(masm_, "[ Body"); |
| 87 ASSERT(loop_depth() == 0); |
87 VisitStatements(fun->body()); | 88 VisitStatements(fun->body()); |
| 89 ASSERT(loop_depth() == 0); |
88 } | 90 } |
89 | 91 |
90 { Comment cmnt(masm_, "[ return <undefined>;"); | 92 { Comment cmnt(masm_, "[ return <undefined>;"); |
91 // Emit a 'return undefined' in case control fell off the end of the | 93 // Emit a 'return undefined' in case control fell off the end of the |
92 // body. | 94 // body. |
93 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 95 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
94 } | 96 } |
95 { Comment cmnt(masm_, "Return sequence"); | 97 { Comment cmnt(masm_, "Return sequence"); |
96 SetReturnPosition(fun); | 98 SetReturnPosition(fun); |
97 | 99 |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 // is no test rax instruction here. | 355 // is no test rax instruction here. |
354 DropAndMove(expr->context(), rax); | 356 DropAndMove(expr->context(), rax); |
355 } else { | 357 } else { |
356 Comment cmnt(masm_, "Stack slot"); | 358 Comment cmnt(masm_, "Stack slot"); |
357 Move(expr->context(), rewrite->AsSlot()); | 359 Move(expr->context(), rewrite->AsSlot()); |
358 } | 360 } |
359 } | 361 } |
360 | 362 |
361 | 363 |
362 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 364 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
363 Comment cmnt(masm_, "[ RegExp Literal"); | 365 Comment cmnt(masm_, "[ RegExpLiteral"); |
364 Label done; | 366 Label done; |
365 // Registers will be used as follows: | 367 // Registers will be used as follows: |
366 // rdi = JS function. | 368 // rdi = JS function. |
367 // rbx = literals array. | 369 // rbx = literals array. |
368 // rax = regexp literal. | 370 // rax = regexp literal. |
369 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 371 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
370 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); | 372 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); |
371 int literal_offset = | 373 int literal_offset = |
372 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; | 374 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
373 __ movq(rax, FieldOperand(rbx, literal_offset)); | 375 __ movq(rax, FieldOperand(rbx, literal_offset)); |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 __ push(rax); | 850 __ push(rax); |
849 // Push receiver object on stack. | 851 // Push receiver object on stack. |
850 if (prop->is_synthetic()) { | 852 if (prop->is_synthetic()) { |
851 __ push(CodeGenerator::GlobalObject()); | 853 __ push(CodeGenerator::GlobalObject()); |
852 } else { | 854 } else { |
853 __ push(rbx); | 855 __ push(rbx); |
854 } | 856 } |
855 EmitCallWithStub(expr); | 857 EmitCallWithStub(expr); |
856 } | 858 } |
857 } else { | 859 } else { |
858 // Call to some other function expression. | 860 // Call to some other expression. If the expression is an anonymous |
859 Visit(expr->expression()); | 861 // function literal not called in a loop, mark it as one that should |
| 862 // also use the fast code generator. |
| 863 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
| 864 if (lit != NULL && |
| 865 lit->name()->Equals(Heap::empty_string()) && |
| 866 loop_depth() == 0) { |
| 867 lit->mark_as_fast(); |
| 868 } |
| 869 Visit(fun); |
860 // Load global receiver object. | 870 // Load global receiver object. |
861 __ movq(rbx, CodeGenerator::GlobalObject()); | 871 __ movq(rbx, CodeGenerator::GlobalObject()); |
862 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 872 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
863 // Emit function call. | 873 // Emit function call. |
864 EmitCallWithStub(expr); | 874 EmitCallWithStub(expr); |
865 } | 875 } |
866 } | 876 } |
867 | 877 |
868 | 878 |
869 void FastCodeGenerator::VisitCallNew(CallNew* expr) { | 879 void FastCodeGenerator::VisitCallNew(CallNew* expr) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 for (int i = 0; i < arg_count; i++) { | 928 for (int i = 0; i < arg_count; i++) { |
919 Visit(args->at(i)); | 929 Visit(args->at(i)); |
920 ASSERT_EQ(Expression::kValue, args->at(i)->context()); | 930 ASSERT_EQ(Expression::kValue, args->at(i)->context()); |
921 } | 931 } |
922 | 932 |
923 __ CallRuntime(function, arg_count); | 933 __ CallRuntime(function, arg_count); |
924 Move(expr->context(), rax); | 934 Move(expr->context(), rax); |
925 } | 935 } |
926 | 936 |
927 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { | 937 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
928 VariableProxy* v = expr->expression()->AsVariableProxy(); | 938 Comment cmnt(masm_, "[ CountOperation"); |
929 ASSERT(v->AsVariable() != NULL); | 939 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
930 ASSERT(v->AsVariable()->is_global()); | 940 ASSERT(proxy->AsVariable() != NULL); |
| 941 ASSERT(proxy->AsVariable()->is_global()); |
931 | 942 |
932 Visit(v); | 943 Visit(proxy); |
933 | |
934 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 944 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
935 | 945 |
936 switch (expr->context()) { | 946 switch (expr->context()) { |
937 case Expression::kUninitialized: | 947 case Expression::kUninitialized: |
938 UNREACHABLE(); | 948 UNREACHABLE(); |
939 case Expression::kValue: // Fall through | 949 case Expression::kValue: // Fall through |
940 case Expression::kTest: // Fall through | 950 case Expression::kTest: // Fall through |
941 case Expression::kTestValue: // Fall through | 951 case Expression::kTestValue: // Fall through |
942 case Expression::kValueTest: | 952 case Expression::kValueTest: |
943 // Duplicate the result on the stack. | 953 // Duplicate the result on the stack. |
944 __ push(rax); | 954 __ push(rax); |
945 break; | 955 break; |
946 case Expression::kEffect: | 956 case Expression::kEffect: |
947 // Do not save result. | 957 // Do not save result. |
948 break; | 958 break; |
949 } | 959 } |
950 // Call runtime for +1/-1. | 960 // Call runtime for +1/-1. |
951 __ push(rax); | 961 __ push(rax); |
952 __ Push(Smi::FromInt(1)); | 962 __ Push(Smi::FromInt(1)); |
953 if (expr->op() == Token::INC) { | 963 if (expr->op() == Token::INC) { |
954 __ CallRuntime(Runtime::kNumberAdd, 2); | 964 __ CallRuntime(Runtime::kNumberAdd, 2); |
955 } else { | 965 } else { |
956 __ CallRuntime(Runtime::kNumberSub, 2); | 966 __ CallRuntime(Runtime::kNumberSub, 2); |
957 } | 967 } |
958 // Call Store IC. | 968 // Call Store IC. |
959 __ Move(rcx, v->AsVariable()->name()); | 969 __ Move(rcx, proxy->AsVariable()->name()); |
960 __ push(CodeGenerator::GlobalObject()); | 970 __ push(CodeGenerator::GlobalObject()); |
961 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 971 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
962 __ call(ic, RelocInfo::CODE_TARGET); | 972 __ call(ic, RelocInfo::CODE_TARGET); |
963 // Restore up stack after store IC | 973 // Restore up stack after store IC |
964 __ addq(rsp, Immediate(kPointerSize)); | 974 __ addq(rsp, Immediate(kPointerSize)); |
965 | 975 |
966 switch (expr->context()) { | 976 switch (expr->context()) { |
967 case Expression::kUninitialized: | 977 case Expression::kUninitialized: |
968 UNREACHABLE(); | 978 UNREACHABLE(); |
969 case Expression::kEffect: // Fall through | 979 case Expression::kEffect: // Fall through |
(...skipping 22 matching lines...) Expand all Loading... |
992 __ addq(rsp, Immediate(kPointerSize)); | 1002 __ addq(rsp, Immediate(kPointerSize)); |
993 __ jmp(true_label_); | 1003 __ jmp(true_label_); |
994 break; | 1004 break; |
995 } | 1005 } |
996 } | 1006 } |
997 } | 1007 } |
998 | 1008 |
999 | 1009 |
1000 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 1010 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
1001 Comment cmnt(masm_, "[ UnaryOperation"); | 1011 Comment cmnt(masm_, "[ UnaryOperation"); |
1002 | |
1003 switch (expr->op()) { | 1012 switch (expr->op()) { |
1004 case Token::VOID: | 1013 case Token::VOID: |
1005 Visit(expr->expression()); | 1014 Visit(expr->expression()); |
1006 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); | 1015 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); |
1007 switch (expr->context()) { | 1016 switch (expr->context()) { |
1008 case Expression::kUninitialized: | 1017 case Expression::kUninitialized: |
1009 UNREACHABLE(); | 1018 UNREACHABLE(); |
1010 break; | 1019 break; |
1011 case Expression::kEffect: | 1020 case Expression::kEffect: |
1012 break; | 1021 break; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 break; | 1094 break; |
1086 } | 1095 } |
1087 | 1096 |
1088 default: | 1097 default: |
1089 UNREACHABLE(); | 1098 UNREACHABLE(); |
1090 } | 1099 } |
1091 } | 1100 } |
1092 | 1101 |
1093 | 1102 |
1094 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 1103 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
| 1104 Comment cmnt(masm_, "[ BinaryOperation"); |
1095 switch (expr->op()) { | 1105 switch (expr->op()) { |
1096 case Token::COMMA: | 1106 case Token::COMMA: |
1097 ASSERT_EQ(Expression::kEffect, expr->left()->context()); | 1107 ASSERT_EQ(Expression::kEffect, expr->left()->context()); |
1098 ASSERT_EQ(expr->context(), expr->right()->context()); | 1108 ASSERT_EQ(expr->context(), expr->right()->context()); |
1099 Visit(expr->left()); | 1109 Visit(expr->left()); |
1100 Visit(expr->right()); | 1110 Visit(expr->right()); |
1101 break; | 1111 break; |
1102 | 1112 |
1103 case Token::OR: | 1113 case Token::OR: |
1104 case Token::AND: | 1114 case Token::AND: |
(...skipping 24 matching lines...) Expand all Loading... |
1129 | 1139 |
1130 break; | 1140 break; |
1131 } | 1141 } |
1132 default: | 1142 default: |
1133 UNREACHABLE(); | 1143 UNREACHABLE(); |
1134 } | 1144 } |
1135 } | 1145 } |
1136 | 1146 |
1137 | 1147 |
1138 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 1148 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 1149 Comment cmnt(masm_, "[ CompareOperation"); |
1139 ASSERT_EQ(Expression::kValue, expr->left()->context()); | 1150 ASSERT_EQ(Expression::kValue, expr->left()->context()); |
1140 ASSERT_EQ(Expression::kValue, expr->right()->context()); | 1151 ASSERT_EQ(Expression::kValue, expr->right()->context()); |
1141 Visit(expr->left()); | 1152 Visit(expr->left()); |
1142 Visit(expr->right()); | 1153 Visit(expr->right()); |
1143 | 1154 |
1144 // Convert current context to test context: Pre-test code. | 1155 // Convert current context to test context: Pre-test code. |
1145 Label push_true; | 1156 Label push_true; |
1146 Label push_false; | 1157 Label push_false; |
1147 Label done; | 1158 Label done; |
1148 Label* saved_true = true_label_; | 1159 Label* saved_true = true_label_; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 true_label_ = saved_true; | 1298 true_label_ = saved_true; |
1288 false_label_ = saved_false; | 1299 false_label_ = saved_false; |
1289 // Convert current context to test context: End post-test code. | 1300 // Convert current context to test context: End post-test code. |
1290 } | 1301 } |
1291 | 1302 |
1292 | 1303 |
1293 #undef __ | 1304 #undef __ |
1294 | 1305 |
1295 | 1306 |
1296 } } // namespace v8::internal | 1307 } } // namespace v8::internal |
OLD | NEW |