| 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 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 TestAndBranch(r0, &discard, false_label_); | 810 TestAndBranch(r0, &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 __ mov(r2, Operand(key->handle())); | 823 __ mov(r2, Operand(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, r0); | |
| 828 } | 826 } |
| 829 | 827 |
| 830 | 828 |
| 831 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop, | 829 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 832 Expression::Context context) { | |
| 833 SetSourcePosition(prop->position()); | 830 SetSourcePosition(prop->position()); |
| 834 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 831 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 835 __ Call(ic, RelocInfo::CODE_TARGET); | 832 __ Call(ic, RelocInfo::CODE_TARGET); |
| 836 Apply(context, r0); | |
| 837 } | 833 } |
| 838 | 834 |
| 839 | 835 |
| 840 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, | 836 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, |
| 841 Expression::Context context) { | 837 Expression::Context context) { |
| 842 __ pop(r0); | 838 __ pop(r0); |
| 843 __ pop(r1); | 839 __ pop(r1); |
| 844 GenericBinaryOpStub stub(op, | 840 GenericBinaryOpStub stub(op, |
| 845 NO_OVERWRITE); | 841 NO_OVERWRITE); |
| 846 __ CallStub(&stub); | 842 __ CallStub(&stub); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 | 959 |
| 964 // If the assignment starts a block of assignments to the same object, | 960 // If the assignment starts a block of assignments to the same object, |
| 965 // change to slow case to avoid the quadratic behavior of repeatedly | 961 // change to slow case to avoid the quadratic behavior of repeatedly |
| 966 // adding fast properties. | 962 // adding fast properties. |
| 967 if (expr->starts_initialization_block()) { | 963 if (expr->starts_initialization_block()) { |
| 968 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. | 964 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. |
| 969 __ push(ip); | 965 __ push(ip); |
| 970 __ CallRuntime(Runtime::kToSlowProperties, 1); | 966 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 971 } | 967 } |
| 972 | 968 |
| 969 // Record source code position before IC call. |
| 970 SetSourcePosition(expr->position()); |
| 971 |
| 973 __ pop(r0); | 972 __ pop(r0); |
| 974 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 973 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 975 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 974 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 976 __ Call(ic, RelocInfo::CODE_TARGET); | 975 __ Call(ic, RelocInfo::CODE_TARGET); |
| 977 | 976 |
| 978 // If the assignment ends an initialization block, revert to fast case. | 977 // If the assignment ends an initialization block, revert to fast case. |
| 979 if (expr->ends_initialization_block()) { | 978 if (expr->ends_initialization_block()) { |
| 980 __ push(r0); // Result of assignment, saved even if not needed. | 979 __ push(r0); // Result of assignment, saved even if not needed. |
| 981 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. | 980 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. |
| 982 __ push(ip); | 981 __ push(ip); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 994 // If the assignment starts a block of assignments to the same object, | 993 // If the assignment starts a block of assignments to the same object, |
| 995 // change to slow case to avoid the quadratic behavior of repeatedly | 994 // change to slow case to avoid the quadratic behavior of repeatedly |
| 996 // adding fast properties. | 995 // adding fast properties. |
| 997 if (expr->starts_initialization_block()) { | 996 if (expr->starts_initialization_block()) { |
| 998 // Receiver is under the key and value. | 997 // Receiver is under the key and value. |
| 999 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); | 998 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); |
| 1000 __ push(ip); | 999 __ push(ip); |
| 1001 __ CallRuntime(Runtime::kToSlowProperties, 1); | 1000 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 1002 } | 1001 } |
| 1003 | 1002 |
| 1003 // Record source code position before IC call. |
| 1004 SetSourcePosition(expr->position()); |
| 1005 |
| 1004 __ pop(r0); | 1006 __ pop(r0); |
| 1005 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1007 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 1006 __ Call(ic, RelocInfo::CODE_TARGET); | 1008 __ Call(ic, RelocInfo::CODE_TARGET); |
| 1007 | 1009 |
| 1008 // If the assignment ends an initialization block, revert to fast case. | 1010 // If the assignment ends an initialization block, revert to fast case. |
| 1009 if (expr->ends_initialization_block()) { | 1011 if (expr->ends_initialization_block()) { |
| 1010 __ push(r0); // Result of assignment, saved even if not needed. | 1012 __ push(r0); // Result of assignment, saved even if not needed. |
| 1011 // Reciever is under the key and value. | 1013 // Reciever is under the key and value. |
| 1012 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); | 1014 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); |
| 1013 __ push(ip); | 1015 __ push(ip); |
| 1014 __ CallRuntime(Runtime::kToFastProperties, 1); | 1016 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1015 __ pop(r0); | 1017 __ pop(r0); |
| 1016 } | 1018 } |
| 1017 | 1019 |
| 1018 // Receiver and key are still on stack. | 1020 // Receiver and key are still on stack. |
| 1019 DropAndApply(2, expr->context(), r0); | 1021 DropAndApply(2, expr->context(), r0); |
| 1020 } | 1022 } |
| 1021 | 1023 |
| 1022 | 1024 |
| 1023 void FastCodeGenerator::VisitProperty(Property* expr) { | 1025 void FastCodeGenerator::VisitProperty(Property* expr) { |
| 1024 Comment cmnt(masm_, "[ Property"); | 1026 Comment cmnt(masm_, "[ Property"); |
| 1025 Expression* key = expr->key(); | 1027 Expression* key = expr->key(); |
| 1026 | 1028 |
| 1027 // Record the source position for the property load. | |
| 1028 SetSourcePosition(expr->position()); | |
| 1029 | |
| 1030 // Evaluate receiver. | 1029 // Evaluate receiver. |
| 1031 Visit(expr->obj()); | 1030 Visit(expr->obj()); |
| 1032 | 1031 |
| 1033 if (key->IsPropertyName()) { | 1032 if (key->IsPropertyName()) { |
| 1034 // Do a named property load. The IC expects the property name in r2 and | 1033 EmitNamedPropertyLoad(expr); |
| 1035 // the receiver on the stack. | 1034 // Drop receiver left on the stack by IC. |
| 1036 __ mov(r2, Operand(key->AsLiteral()->handle())); | |
| 1037 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | |
| 1038 __ Call(ic, RelocInfo::CODE_TARGET); | |
| 1039 DropAndApply(1, expr->context(), r0); | 1035 DropAndApply(1, expr->context(), r0); |
| 1040 } else { | 1036 } else { |
| 1041 // Do a keyed property load. | |
| 1042 Visit(expr->key()); | 1037 Visit(expr->key()); |
| 1043 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1038 EmitKeyedPropertyLoad(expr); |
| 1044 __ Call(ic, RelocInfo::CODE_TARGET); | |
| 1045 // Drop key and receiver left on the stack by IC. | 1039 // Drop key and receiver left on the stack by IC. |
| 1046 DropAndApply(2, expr->context(), r0); | 1040 DropAndApply(2, expr->context(), r0); |
| 1047 } | 1041 } |
| 1048 } | 1042 } |
| 1049 | 1043 |
| 1050 void FastCodeGenerator::EmitCallWithIC(Call* expr, | 1044 void FastCodeGenerator::EmitCallWithIC(Call* expr, |
| 1051 Handle<Object> ignored, | 1045 Handle<Object> ignored, |
| 1052 RelocInfo::Mode mode) { | 1046 RelocInfo::Mode mode) { |
| 1053 // Code common for calls using the IC. | 1047 // Code common for calls using the IC. |
| 1054 ZoneList<Expression*>* args = expr->arguments(); | 1048 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 } else { | 1370 } else { |
| 1377 // Reserve space for result of postfix operation. | 1371 // Reserve space for result of postfix operation. |
| 1378 if (expr->is_postfix() && expr->context() != Expression::kEffect) { | 1372 if (expr->is_postfix() && expr->context() != Expression::kEffect) { |
| 1379 ASSERT(expr->context() != Expression::kUninitialized); | 1373 ASSERT(expr->context() != Expression::kUninitialized); |
| 1380 __ mov(ip, Operand(Smi::FromInt(0))); | 1374 __ mov(ip, Operand(Smi::FromInt(0))); |
| 1381 __ push(ip); | 1375 __ push(ip); |
| 1382 } | 1376 } |
| 1383 Visit(prop->obj()); | 1377 Visit(prop->obj()); |
| 1384 ASSERT_EQ(Expression::kValue, prop->obj()->context()); | 1378 ASSERT_EQ(Expression::kValue, prop->obj()->context()); |
| 1385 if (assign_type == NAMED_PROPERTY) { | 1379 if (assign_type == NAMED_PROPERTY) { |
| 1386 EmitNamedPropertyLoad(prop, Expression::kValue); | 1380 EmitNamedPropertyLoad(prop); |
| 1387 } else { | 1381 } else { |
| 1388 Visit(prop->key()); | 1382 Visit(prop->key()); |
| 1389 ASSERT_EQ(Expression::kValue, prop->key()->context()); | 1383 ASSERT_EQ(Expression::kValue, prop->key()->context()); |
| 1390 EmitKeyedPropertyLoad(prop, Expression::kValue); | 1384 EmitKeyedPropertyLoad(prop); |
| 1391 } | 1385 } |
| 1386 __ push(r0); |
| 1392 } | 1387 } |
| 1393 | 1388 |
| 1394 // Convert to number. | 1389 // Convert to number. |
| 1395 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); | 1390 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); |
| 1396 | 1391 |
| 1397 // Save result for postfix expressions. | 1392 // Save result for postfix expressions. |
| 1398 if (expr->is_postfix()) { | 1393 if (expr->is_postfix()) { |
| 1399 switch (expr->context()) { | 1394 switch (expr->context()) { |
| 1400 case Expression::kUninitialized: | 1395 case Expression::kUninitialized: |
| 1401 UNREACHABLE(); | 1396 UNREACHABLE(); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 __ pop(result_register()); | 1722 __ pop(result_register()); |
| 1728 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1723 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
| 1729 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1724 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 1730 __ add(pc, r1, Operand(masm_->CodeObject())); | 1725 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 1731 } | 1726 } |
| 1732 | 1727 |
| 1733 | 1728 |
| 1734 #undef __ | 1729 #undef __ |
| 1735 | 1730 |
| 1736 } } // namespace v8::internal | 1731 } } // namespace v8::internal |
| OLD | NEW |