Chromium Code Reviews| 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 |