| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 StackCheckStub stub; | 78 StackCheckStub stub; |
| 79 __ CallStub(&stub); | 79 __ CallStub(&stub); |
| 80 __ bind(&ok); | 80 __ bind(&ok); |
| 81 } | 81 } |
| 82 | 82 |
| 83 if (FLAG_trace) { | 83 if (FLAG_trace) { |
| 84 __ CallRuntime(Runtime::kTraceEnter, 0); | 84 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 85 } | 85 } |
| 86 | 86 |
| 87 { Comment cmnt(masm_, "[ Body"); | 87 { Comment cmnt(masm_, "[ Body"); |
| 88 ASSERT(loop_depth() == 0); |
| 88 VisitStatements(fun->body()); | 89 VisitStatements(fun->body()); |
| 90 ASSERT(loop_depth() == 0); |
| 89 } | 91 } |
| 90 | 92 |
| 91 { Comment cmnt(masm_, "[ return <undefined>;"); | 93 { Comment cmnt(masm_, "[ return <undefined>;"); |
| 92 // Emit a 'return undefined' in case control fell off the end of the | 94 // Emit a 'return undefined' in case control fell off the end of the |
| 93 // body. | 95 // body. |
| 94 __ mov(eax, Factory::undefined_value()); | 96 __ mov(eax, Factory::undefined_value()); |
| 95 } | 97 } |
| 96 { Comment cmnt(masm_, "[ Return sequence"); | 98 { Comment cmnt(masm_, "[ Return sequence"); |
| 97 SetReturnPosition(fun); | 99 SetReturnPosition(fun); |
| 98 | 100 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 | 337 |
| 336 DropAndMove(expr->context(), eax); | 338 DropAndMove(expr->context(), eax); |
| 337 } else { | 339 } else { |
| 338 Comment cmnt(masm_, "Stack slot"); | 340 Comment cmnt(masm_, "Stack slot"); |
| 339 Move(expr->context(), rewrite->AsSlot()); | 341 Move(expr->context(), rewrite->AsSlot()); |
| 340 } | 342 } |
| 341 } | 343 } |
| 342 | 344 |
| 343 | 345 |
| 344 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 346 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 345 Comment cmnt(masm_, "[ RegExp Literal"); | 347 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 346 Label done; | 348 Label done; |
| 347 // Registers will be used as follows: | 349 // Registers will be used as follows: |
| 348 // edi = JS function. | 350 // edi = JS function. |
| 349 // ebx = literals array. | 351 // ebx = literals array. |
| 350 // eax = regexp literal. | 352 // eax = regexp literal. |
| 351 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 353 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 352 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 354 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
| 353 int literal_offset = | 355 int literal_offset = |
| 354 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; | 356 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
| 355 __ mov(eax, FieldOperand(ebx, literal_offset)); | 357 __ mov(eax, FieldOperand(ebx, literal_offset)); |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 __ push(eax); | 835 __ push(eax); |
| 834 // Push receiver object on stack. | 836 // Push receiver object on stack. |
| 835 if (prop->is_synthetic()) { | 837 if (prop->is_synthetic()) { |
| 836 __ push(CodeGenerator::GlobalObject()); | 838 __ push(CodeGenerator::GlobalObject()); |
| 837 } else { | 839 } else { |
| 838 __ push(ebx); | 840 __ push(ebx); |
| 839 } | 841 } |
| 840 EmitCallWithStub(expr); | 842 EmitCallWithStub(expr); |
| 841 } | 843 } |
| 842 } else { | 844 } else { |
| 843 // Call to some other function expression. | 845 // Call to some other expression. If the expression is an anonymous |
| 844 Visit(expr->expression()); | 846 // function literal not called in a loop, mark it as one that should |
| 847 // also use the fast code generator. |
| 848 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
| 849 if (lit != NULL && |
| 850 lit->name()->Equals(Heap::empty_string()) && |
| 851 loop_depth() == 0) { |
| 852 lit->mark_as_fast(); |
| 853 } |
| 854 Visit(fun); |
| 845 // Load global receiver object. | 855 // Load global receiver object. |
| 846 __ mov(ebx, CodeGenerator::GlobalObject()); | 856 __ mov(ebx, CodeGenerator::GlobalObject()); |
| 847 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); | 857 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); |
| 848 // Emit function call. | 858 // Emit function call. |
| 849 EmitCallWithStub(expr); | 859 EmitCallWithStub(expr); |
| 850 } | 860 } |
| 851 } | 861 } |
| 852 | 862 |
| 863 |
| 853 void FastCodeGenerator::VisitCallNew(CallNew* expr) { | 864 void FastCodeGenerator::VisitCallNew(CallNew* expr) { |
| 854 Comment cmnt(masm_, "[ CallNew"); | 865 Comment cmnt(masm_, "[ CallNew"); |
| 855 // According to ECMA-262, section 11.2.2, page 44, the function | 866 // According to ECMA-262, section 11.2.2, page 44, the function |
| 856 // expression in new calls must be evaluated before the | 867 // expression in new calls must be evaluated before the |
| 857 // arguments. | 868 // arguments. |
| 858 // Push function on the stack. | 869 // Push function on the stack. |
| 859 Visit(expr->expression()); | 870 Visit(expr->expression()); |
| 860 ASSERT_EQ(Expression::kValue, expr->expression()->context()); | 871 ASSERT_EQ(Expression::kValue, expr->expression()->context()); |
| 861 | 872 |
| 862 // Push global object (receiver). | 873 // Push global object (receiver). |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 ASSERT_EQ(Expression::kValue, args->at(i)->context()); | 914 ASSERT_EQ(Expression::kValue, args->at(i)->context()); |
| 904 } | 915 } |
| 905 | 916 |
| 906 __ CallRuntime(function, arg_count); | 917 __ CallRuntime(function, arg_count); |
| 907 Move(expr->context(), eax); | 918 Move(expr->context(), eax); |
| 908 } | 919 } |
| 909 | 920 |
| 910 | 921 |
| 911 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 922 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 912 Comment cmnt(masm_, "[ UnaryOperation"); | 923 Comment cmnt(masm_, "[ UnaryOperation"); |
| 913 | |
| 914 switch (expr->op()) { | 924 switch (expr->op()) { |
| 915 case Token::VOID: | 925 case Token::VOID: |
| 916 Visit(expr->expression()); | 926 Visit(expr->expression()); |
| 917 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); | 927 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); |
| 918 switch (expr->context()) { | 928 switch (expr->context()) { |
| 919 case Expression::kUninitialized: | 929 case Expression::kUninitialized: |
| 920 UNREACHABLE(); | 930 UNREACHABLE(); |
| 921 break; | 931 break; |
| 922 case Expression::kEffect: | 932 case Expression::kEffect: |
| 923 break; | 933 break; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 break; | 1006 break; |
| 997 } | 1007 } |
| 998 | 1008 |
| 999 default: | 1009 default: |
| 1000 UNREACHABLE(); | 1010 UNREACHABLE(); |
| 1001 } | 1011 } |
| 1002 } | 1012 } |
| 1003 | 1013 |
| 1004 | 1014 |
| 1005 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { | 1015 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 1006 VariableProxy* v = expr->expression()->AsVariableProxy(); | 1016 Comment cmnt(masm_, "[ CountOperation"); |
| 1007 ASSERT(v->AsVariable() != NULL); | 1017 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 1008 ASSERT(v->AsVariable()->is_global()); | 1018 ASSERT(proxy->AsVariable() != NULL); |
| 1019 ASSERT(proxy->AsVariable()->is_global()); |
| 1009 | 1020 |
| 1010 Visit(v); | 1021 Visit(proxy); |
| 1011 | |
| 1012 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 1022 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
| 1013 | 1023 |
| 1014 switch (expr->context()) { | 1024 switch (expr->context()) { |
| 1015 case Expression::kUninitialized: | 1025 case Expression::kUninitialized: |
| 1016 UNREACHABLE(); | 1026 UNREACHABLE(); |
| 1017 case Expression::kValue: // Fall through | 1027 case Expression::kValue: // Fall through |
| 1018 case Expression::kTest: // Fall through | 1028 case Expression::kTest: // Fall through |
| 1019 case Expression::kTestValue: // Fall through | 1029 case Expression::kTestValue: // Fall through |
| 1020 case Expression::kValueTest: | 1030 case Expression::kValueTest: |
| 1021 // Duplicate the result on the stack. | 1031 // Duplicate the result on the stack. |
| 1022 __ push(eax); | 1032 __ push(eax); |
| 1023 break; | 1033 break; |
| 1024 case Expression::kEffect: | 1034 case Expression::kEffect: |
| 1025 // Do not save result. | 1035 // Do not save result. |
| 1026 break; | 1036 break; |
| 1027 } | 1037 } |
| 1028 // Call runtime for +1/-1. | 1038 // Call runtime for +1/-1. |
| 1029 __ push(eax); | 1039 __ push(eax); |
| 1030 __ push(Immediate(Smi::FromInt(1))); | 1040 __ push(Immediate(Smi::FromInt(1))); |
| 1031 if (expr->op() == Token::INC) { | 1041 if (expr->op() == Token::INC) { |
| 1032 __ CallRuntime(Runtime::kNumberAdd, 2); | 1042 __ CallRuntime(Runtime::kNumberAdd, 2); |
| 1033 } else { | 1043 } else { |
| 1034 __ CallRuntime(Runtime::kNumberSub, 2); | 1044 __ CallRuntime(Runtime::kNumberSub, 2); |
| 1035 } | 1045 } |
| 1036 // Call Store IC. | 1046 // Call Store IC. |
| 1037 __ mov(ecx, v->AsVariable()->name()); | 1047 __ mov(ecx, proxy->AsVariable()->name()); |
| 1038 __ push(CodeGenerator::GlobalObject()); | 1048 __ push(CodeGenerator::GlobalObject()); |
| 1039 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1049 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1040 __ call(ic, RelocInfo::CODE_TARGET); | 1050 __ call(ic, RelocInfo::CODE_TARGET); |
| 1041 // Restore up stack after store IC. | 1051 // Restore up stack after store IC. |
| 1042 __ add(Operand(esp), Immediate(kPointerSize)); | 1052 __ add(Operand(esp), Immediate(kPointerSize)); |
| 1043 | 1053 |
| 1044 switch (expr->context()) { | 1054 switch (expr->context()) { |
| 1045 case Expression::kUninitialized: | 1055 case Expression::kUninitialized: |
| 1046 UNREACHABLE(); | 1056 UNREACHABLE(); |
| 1047 case Expression::kEffect: // Fall through | 1057 case Expression::kEffect: // Fall through |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1069 __ bind(&discard); | 1079 __ bind(&discard); |
| 1070 __ add(Operand(esp), Immediate(kPointerSize)); | 1080 __ add(Operand(esp), Immediate(kPointerSize)); |
| 1071 __ jmp(true_label_); | 1081 __ jmp(true_label_); |
| 1072 break; | 1082 break; |
| 1073 } | 1083 } |
| 1074 } | 1084 } |
| 1075 } | 1085 } |
| 1076 | 1086 |
| 1077 | 1087 |
| 1078 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 1088 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
| 1089 Comment cmnt(masm_, "[ BinaryOperation"); |
| 1079 switch (expr->op()) { | 1090 switch (expr->op()) { |
| 1080 case Token::COMMA: | 1091 case Token::COMMA: |
| 1081 ASSERT_EQ(Expression::kEffect, expr->left()->context()); | 1092 ASSERT_EQ(Expression::kEffect, expr->left()->context()); |
| 1082 ASSERT_EQ(expr->context(), expr->right()->context()); | 1093 ASSERT_EQ(expr->context(), expr->right()->context()); |
| 1083 Visit(expr->left()); | 1094 Visit(expr->left()); |
| 1084 Visit(expr->right()); | 1095 Visit(expr->right()); |
| 1085 break; | 1096 break; |
| 1086 | 1097 |
| 1087 case Token::OR: | 1098 case Token::OR: |
| 1088 case Token::AND: | 1099 case Token::AND: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1113 | 1124 |
| 1114 break; | 1125 break; |
| 1115 } | 1126 } |
| 1116 default: | 1127 default: |
| 1117 UNREACHABLE(); | 1128 UNREACHABLE(); |
| 1118 } | 1129 } |
| 1119 } | 1130 } |
| 1120 | 1131 |
| 1121 | 1132 |
| 1122 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 1133 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 1134 Comment cmnt(masm_, "[ CompareOperation"); |
| 1123 ASSERT_EQ(Expression::kValue, expr->left()->context()); | 1135 ASSERT_EQ(Expression::kValue, expr->left()->context()); |
| 1124 ASSERT_EQ(Expression::kValue, expr->right()->context()); | 1136 ASSERT_EQ(Expression::kValue, expr->right()->context()); |
| 1125 Visit(expr->left()); | 1137 Visit(expr->left()); |
| 1126 Visit(expr->right()); | 1138 Visit(expr->right()); |
| 1127 | 1139 |
| 1128 // Convert current context to test context: Pre-test code. | 1140 // Convert current context to test context: Pre-test code. |
| 1129 Label push_true; | 1141 Label push_true; |
| 1130 Label push_false; | 1142 Label push_false; |
| 1131 Label done; | 1143 Label done; |
| 1132 Label* saved_true = true_label_; | 1144 Label* saved_true = true_label_; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 true_label_ = saved_true; | 1286 true_label_ = saved_true; |
| 1275 false_label_ = saved_false; | 1287 false_label_ = saved_false; |
| 1276 // Convert current context to test context: End post-test code. | 1288 // Convert current context to test context: End post-test code. |
| 1277 } | 1289 } |
| 1278 | 1290 |
| 1279 | 1291 |
| 1280 #undef __ | 1292 #undef __ |
| 1281 | 1293 |
| 1282 | 1294 |
| 1283 } } // namespace v8::internal | 1295 } } // namespace v8::internal |
| OLD | NEW |