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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 | 85 |
86 { Comment cmnt(masm_, "[ Declarations"); | 86 { Comment cmnt(masm_, "[ Declarations"); |
87 VisitDeclarations(fun->scope()->declarations()); | 87 VisitDeclarations(fun->scope()->declarations()); |
88 } | 88 } |
89 | 89 |
90 if (FLAG_trace) { | 90 if (FLAG_trace) { |
91 __ CallRuntime(Runtime::kTraceEnter, 0); | 91 __ CallRuntime(Runtime::kTraceEnter, 0); |
92 } | 92 } |
93 | 93 |
94 { Comment cmnt(masm_, "[ Body"); | 94 { Comment cmnt(masm_, "[ Body"); |
95 ASSERT(loop_depth() == 0); | |
95 VisitStatements(fun->body()); | 96 VisitStatements(fun->body()); |
97 ASSERT(loop_depth() == 0); | |
fschneider
2009/11/03 14:10:13
Why this duplicate ASSERT? (also on ia32, x64)
Kevin Millikin (Chromium)
2009/11/03 14:16:09
We should not be in a loop before we compile the b
| |
96 } | 98 } |
97 | 99 |
98 { Comment cmnt(masm_, "[ return <undefined>;"); | 100 { Comment cmnt(masm_, "[ return <undefined>;"); |
99 // Emit a 'return undefined' in case control fell off the end of the | 101 // Emit a 'return undefined' in case control fell off the end of the |
100 // body. | 102 // body. |
101 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 103 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
102 } | 104 } |
103 { Comment cmnt(masm_, "Return sequence"); | 105 { Comment cmnt(masm_, "Return sequence"); |
104 if (return_label_.is_bound()) { | 106 if (return_label_.is_bound()) { |
105 __ b(&return_label_); | 107 __ b(&return_label_); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 318 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
317 DropAndMove(expr->context(), r0); | 319 DropAndMove(expr->context(), r0); |
318 } else { | 320 } else { |
319 Comment cmnt(masm_, "Stack slot"); | 321 Comment cmnt(masm_, "Stack slot"); |
320 Move(expr->context(), rewrite->AsSlot()); | 322 Move(expr->context(), rewrite->AsSlot()); |
321 } | 323 } |
322 } | 324 } |
323 | 325 |
324 | 326 |
325 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 327 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
326 Comment cmnt(masm_, "[ RegExp Literal"); | 328 Comment cmnt(masm_, "[ RegExpLiteral"); |
327 Label done; | 329 Label done; |
328 // Registers will be used as follows: | 330 // Registers will be used as follows: |
329 // r4 = JS function, literals array | 331 // r4 = JS function, literals array |
330 // r3 = literal index | 332 // r3 = literal index |
331 // r2 = RegExp pattern | 333 // r2 = RegExp pattern |
332 // r1 = RegExp flags | 334 // r1 = RegExp flags |
333 // r0 = temp + return value (RegExp literal) | 335 // r0 = temp + return value (RegExp literal) |
334 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 336 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
335 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); | 337 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); |
336 int literal_offset = | 338 int literal_offset = |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
811 __ ldr(r1, CodeGenerator::GlobalObject()); | 813 __ ldr(r1, CodeGenerator::GlobalObject()); |
812 } else { | 814 } else { |
813 __ ldr(r1, MemOperand(sp, kPointerSize)); | 815 __ ldr(r1, MemOperand(sp, kPointerSize)); |
814 } | 816 } |
815 // Overwrite (object, key) with (function, receiver). | 817 // Overwrite (object, key) with (function, receiver). |
816 __ str(r0, MemOperand(sp, kPointerSize)); | 818 __ str(r0, MemOperand(sp, kPointerSize)); |
817 __ str(r1, MemOperand(sp)); | 819 __ str(r1, MemOperand(sp)); |
818 EmitCallWithStub(expr); | 820 EmitCallWithStub(expr); |
819 } | 821 } |
820 } else { | 822 } else { |
821 // Call to some other function expression. | 823 // Call to some other expression. If the expression is an anonymous |
822 Visit(expr->expression()); | 824 // function literal not called in a loop, mark it as one that should |
825 // also use the fast code generator. | |
826 FunctionLiteral* lit = fun->AsFunctionLiteral(); | |
827 if (lit != NULL && | |
828 lit->name()->Equals(Heap::empty_string()) && | |
829 loop_depth() == 0) { | |
830 lit->mark_as_fast(); | |
Søren Thygesen Gjesse
2009/11/03 13:57:47
As this logic is duplicated in all three code gene
Kevin Millikin (Chromium)
2009/11/03 14:16:09
That's a good idea. For now the check is pretty s
| |
831 } | |
832 Visit(fun); | |
823 // Load global receiver object. | 833 // Load global receiver object. |
824 __ ldr(r1, CodeGenerator::GlobalObject()); | 834 __ ldr(r1, CodeGenerator::GlobalObject()); |
825 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 835 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
826 __ push(r1); | 836 __ push(r1); |
827 // Emit function call. | 837 // Emit function call. |
828 EmitCallWithStub(expr); | 838 EmitCallWithStub(expr); |
829 } | 839 } |
830 } | 840 } |
831 | 841 |
832 | 842 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 ASSERT_EQ(Expression::kValue, args->at(i)->context()); | 893 ASSERT_EQ(Expression::kValue, args->at(i)->context()); |
884 } | 894 } |
885 | 895 |
886 __ CallRuntime(function, arg_count); | 896 __ CallRuntime(function, arg_count); |
887 Move(expr->context(), r0); | 897 Move(expr->context(), r0); |
888 } | 898 } |
889 | 899 |
890 | 900 |
891 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 901 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
892 Comment cmnt(masm_, "[ UnaryOperation"); | 902 Comment cmnt(masm_, "[ UnaryOperation"); |
893 | |
894 switch (expr->op()) { | 903 switch (expr->op()) { |
895 case Token::VOID: | 904 case Token::VOID: |
896 Visit(expr->expression()); | 905 Visit(expr->expression()); |
897 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); | 906 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); |
898 switch (expr->context()) { | 907 switch (expr->context()) { |
899 case Expression::kUninitialized: | 908 case Expression::kUninitialized: |
900 UNREACHABLE(); | 909 UNREACHABLE(); |
901 break; | 910 break; |
902 case Expression::kEffect: | 911 case Expression::kEffect: |
903 break; | 912 break; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
981 break; | 990 break; |
982 } | 991 } |
983 | 992 |
984 default: | 993 default: |
985 UNREACHABLE(); | 994 UNREACHABLE(); |
986 } | 995 } |
987 } | 996 } |
988 | 997 |
989 | 998 |
990 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { | 999 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
991 VariableProxy* v = expr->expression()->AsVariableProxy(); | 1000 Comment cmnt(masm_, "[ CountOperation"); |
992 ASSERT(v->AsVariable() != NULL); | 1001 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
993 ASSERT(v->AsVariable()->is_global()); | 1002 ASSERT(proxy->AsVariable() != NULL); |
1003 ASSERT(proxy->AsVariable()->is_global()); | |
994 | 1004 |
995 Visit(v); | 1005 Visit(proxy); |
996 | |
997 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); | 1006 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); |
998 | 1007 |
999 switch (expr->context()) { | 1008 switch (expr->context()) { |
1000 case Expression::kUninitialized: | 1009 case Expression::kUninitialized: |
1001 UNREACHABLE(); | 1010 UNREACHABLE(); |
1002 case Expression::kValue: // Fall through | 1011 case Expression::kValue: // Fall through |
1003 case Expression::kTest: // Fall through | 1012 case Expression::kTest: // Fall through |
1004 case Expression::kTestValue: // Fall through | 1013 case Expression::kTestValue: // Fall through |
1005 case Expression::kValueTest: | 1014 case Expression::kValueTest: |
1006 // Duplicate the result on the stack. | 1015 // Duplicate the result on the stack. |
1007 __ push(r0); | 1016 __ push(r0); |
1008 break; | 1017 break; |
1009 case Expression::kEffect: | 1018 case Expression::kEffect: |
1010 // Do not save result. | 1019 // Do not save result. |
1011 break; | 1020 break; |
1012 } | 1021 } |
1013 // Call runtime for +1/-1. | 1022 // Call runtime for +1/-1. |
1014 __ push(r0); | 1023 __ push(r0); |
1015 __ mov(ip, Operand(Smi::FromInt(1))); | 1024 __ mov(ip, Operand(Smi::FromInt(1))); |
1016 __ push(ip); | 1025 __ push(ip); |
1017 if (expr->op() == Token::INC) { | 1026 if (expr->op() == Token::INC) { |
1018 __ CallRuntime(Runtime::kNumberAdd, 2); | 1027 __ CallRuntime(Runtime::kNumberAdd, 2); |
1019 } else { | 1028 } else { |
1020 __ CallRuntime(Runtime::kNumberSub, 2); | 1029 __ CallRuntime(Runtime::kNumberSub, 2); |
1021 } | 1030 } |
1022 // Call Store IC. | 1031 // Call Store IC. |
1023 __ mov(r2, Operand(v->AsVariable()->name())); | 1032 __ mov(r2, Operand(proxy->AsVariable()->name())); |
1024 __ ldr(ip, CodeGenerator::GlobalObject()); | 1033 __ ldr(ip, CodeGenerator::GlobalObject()); |
1025 __ push(ip); | 1034 __ push(ip); |
1026 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1035 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1027 __ Call(ic, RelocInfo::CODE_TARGET); | 1036 __ Call(ic, RelocInfo::CODE_TARGET); |
1028 // Restore up stack after store IC. | 1037 // Restore up stack after store IC. |
1029 __ add(sp, sp, Operand(kPointerSize)); | 1038 __ add(sp, sp, Operand(kPointerSize)); |
1030 | 1039 |
1031 switch (expr->context()) { | 1040 switch (expr->context()) { |
1032 case Expression::kUninitialized: | 1041 case Expression::kUninitialized: |
1033 UNREACHABLE(); | 1042 UNREACHABLE(); |
(...skipping 22 matching lines...) Expand all Loading... | |
1056 __ bind(&discard); | 1065 __ bind(&discard); |
1057 __ add(sp, sp, Operand(kPointerSize)); | 1066 __ add(sp, sp, Operand(kPointerSize)); |
1058 __ b(true_label_); | 1067 __ b(true_label_); |
1059 break; | 1068 break; |
1060 } | 1069 } |
1061 } | 1070 } |
1062 } | 1071 } |
1063 | 1072 |
1064 | 1073 |
1065 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 1074 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
1075 Comment cmnt(masm_, "[ BinaryOperation"); | |
1066 switch (expr->op()) { | 1076 switch (expr->op()) { |
1067 case Token::COMMA: | 1077 case Token::COMMA: |
1068 ASSERT_EQ(Expression::kEffect, expr->left()->context()); | 1078 ASSERT_EQ(Expression::kEffect, expr->left()->context()); |
1069 ASSERT_EQ(expr->context(), expr->right()->context()); | 1079 ASSERT_EQ(expr->context(), expr->right()->context()); |
1070 Visit(expr->left()); | 1080 Visit(expr->left()); |
1071 Visit(expr->right()); | 1081 Visit(expr->right()); |
1072 break; | 1082 break; |
1073 | 1083 |
1074 case Token::OR: | 1084 case Token::OR: |
1075 case Token::AND: | 1085 case Token::AND: |
(...skipping 25 matching lines...) Expand all Loading... | |
1101 | 1111 |
1102 break; | 1112 break; |
1103 } | 1113 } |
1104 default: | 1114 default: |
1105 UNREACHABLE(); | 1115 UNREACHABLE(); |
1106 } | 1116 } |
1107 } | 1117 } |
1108 | 1118 |
1109 | 1119 |
1110 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 1120 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
1121 Comment cmnt(masm_, "[ CompareOperation"); | |
1111 ASSERT_EQ(Expression::kValue, expr->left()->context()); | 1122 ASSERT_EQ(Expression::kValue, expr->left()->context()); |
1112 ASSERT_EQ(Expression::kValue, expr->right()->context()); | 1123 ASSERT_EQ(Expression::kValue, expr->right()->context()); |
1113 Visit(expr->left()); | 1124 Visit(expr->left()); |
1114 Visit(expr->right()); | 1125 Visit(expr->right()); |
1115 | 1126 |
1116 // Convert current context to test context: Pre-test code. | 1127 // Convert current context to test context: Pre-test code. |
1117 Label push_true; | 1128 Label push_true; |
1118 Label push_false; | 1129 Label push_false; |
1119 Label done; | 1130 Label done; |
1120 Label* saved_true = true_label_; | 1131 Label* saved_true = true_label_; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1266 true_label_ = saved_true; | 1277 true_label_ = saved_true; |
1267 false_label_ = saved_false; | 1278 false_label_ = saved_false; |
1268 // Convert current context to test context: End post-test code. | 1279 // Convert current context to test context: End post-test code. |
1269 } | 1280 } |
1270 | 1281 |
1271 | 1282 |
1272 #undef __ | 1283 #undef __ |
1273 | 1284 |
1274 | 1285 |
1275 } } // namespace v8::internal | 1286 } } // namespace v8::internal |
OLD | NEW |