| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 27 matching lines...) Expand all Loading... |
| 38 #include "scopes.h" | 38 #include "scopes.h" |
| 39 #include "stub-cache.h" | 39 #include "stub-cache.h" |
| 40 | 40 |
| 41 #include "arm/code-stubs-arm.h" | 41 #include "arm/code-stubs-arm.h" |
| 42 | 42 |
| 43 namespace v8 { | 43 namespace v8 { |
| 44 namespace internal { | 44 namespace internal { |
| 45 | 45 |
| 46 #define __ ACCESS_MASM(masm_) | 46 #define __ ACCESS_MASM(masm_) |
| 47 | 47 |
| 48 static unsigned GetPropertyId(Property* property) { |
| 49 if (property->is_synthetic()) return AstNode::kNoNumber; |
| 50 return property->id(); |
| 51 } |
| 52 |
| 48 | 53 |
| 49 // A patch site is a location in the code which it is possible to patch. This | 54 // A patch site is a location in the code which it is possible to patch. This |
| 50 // class has a number of methods to emit the code which is patchable and the | 55 // class has a number of methods to emit the code which is patchable and the |
| 51 // method EmitPatchInfo to record a marker back to the patchable code. This | 56 // method EmitPatchInfo to record a marker back to the patchable code. This |
| 52 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit | 57 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit |
| 53 // immediate value is used) is the delta from the pc to the first instruction of | 58 // immediate value is used) is the delta from the pc to the first instruction of |
| 54 // the patchable code. | 59 // the patchable code. |
| 55 class JumpPatchSite BASE_EMBEDDED { | 60 class JumpPatchSite BASE_EMBEDDED { |
| 56 public: | 61 public: |
| 57 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { | 62 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { |
| (...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 __ b(ne, &next_test); | 837 __ b(ne, &next_test); |
| 833 __ Drop(1); // Switch value is no longer needed. | 838 __ Drop(1); // Switch value is no longer needed. |
| 834 __ b(clause->body_target()); | 839 __ b(clause->body_target()); |
| 835 __ bind(&slow_case); | 840 __ bind(&slow_case); |
| 836 } | 841 } |
| 837 | 842 |
| 838 // Record position before stub call for type feedback. | 843 // Record position before stub call for type feedback. |
| 839 SetSourcePosition(clause->position()); | 844 SetSourcePosition(clause->position()); |
| 840 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 845 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
| 841 EmitCallIC(ic, &patch_site, clause->CompareId()); | 846 EmitCallIC(ic, &patch_site, clause->CompareId()); |
| 847 |
| 842 __ cmp(r0, Operand(0)); | 848 __ cmp(r0, Operand(0)); |
| 843 __ b(ne, &next_test); | 849 __ b(ne, &next_test); |
| 844 __ Drop(1); // Switch value is no longer needed. | 850 __ Drop(1); // Switch value is no longer needed. |
| 845 __ b(clause->body_target()); | 851 __ b(clause->body_target()); |
| 846 } | 852 } |
| 847 | 853 |
| 848 // Discard the test value and jump to the default if present, otherwise to | 854 // Discard the test value and jump to the default if present, otherwise to |
| 849 // the end of the statement. | 855 // the end of the statement. |
| 850 __ bind(&next_test); | 856 __ bind(&next_test); |
| 851 __ Drop(1); // Switch value is no longer needed. | 857 __ Drop(1); // Switch value is no longer needed. |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1221 key_literal->handle()->IsSmi()) { | 1227 key_literal->handle()->IsSmi()) { |
| 1222 // Load arguments object if there are no eval-introduced | 1228 // Load arguments object if there are no eval-introduced |
| 1223 // variables. Then load the argument from the arguments | 1229 // variables. Then load the argument from the arguments |
| 1224 // object using keyed load. | 1230 // object using keyed load. |
| 1225 __ ldr(r1, | 1231 __ ldr(r1, |
| 1226 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1232 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1227 slow)); | 1233 slow)); |
| 1228 __ mov(r0, Operand(key_literal->handle())); | 1234 __ mov(r0, Operand(key_literal->handle())); |
| 1229 Handle<Code> ic = | 1235 Handle<Code> ic = |
| 1230 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1236 isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1231 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1237 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
| 1232 __ jmp(done); | 1238 __ jmp(done); |
| 1233 } | 1239 } |
| 1234 } | 1240 } |
| 1235 } | 1241 } |
| 1236 } | 1242 } |
| 1237 } | 1243 } |
| 1238 | 1244 |
| 1239 | 1245 |
| 1240 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1246 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1241 // Four cases: non-this global variables, lookup slots, all other | 1247 // Four cases: non-this global variables, lookup slots, all other |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 // Assert that the key is a smi. | 1309 // Assert that the key is a smi. |
| 1304 Literal* key_literal = property->key()->AsLiteral(); | 1310 Literal* key_literal = property->key()->AsLiteral(); |
| 1305 ASSERT_NOT_NULL(key_literal); | 1311 ASSERT_NOT_NULL(key_literal); |
| 1306 ASSERT(key_literal->handle()->IsSmi()); | 1312 ASSERT(key_literal->handle()->IsSmi()); |
| 1307 | 1313 |
| 1308 // Load the key. | 1314 // Load the key. |
| 1309 __ mov(r0, Operand(key_literal->handle())); | 1315 __ mov(r0, Operand(key_literal->handle())); |
| 1310 | 1316 |
| 1311 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1317 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1312 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1318 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1313 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1319 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
| 1314 context()->Plug(r0); | 1320 context()->Plug(r0); |
| 1315 } | 1321 } |
| 1316 } | 1322 } |
| 1317 | 1323 |
| 1318 | 1324 |
| 1319 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1325 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1320 Comment cmnt(masm_, "[ RegExpLiteral"); | 1326 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1321 Label materialized; | 1327 Label materialized; |
| 1322 // Registers will be used as follows: | 1328 // Registers will be used as follows: |
| 1323 // r5 = materialized value (RegExp literal) | 1329 // r5 = materialized value (RegExp literal) |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1414 // Fall through. | 1420 // Fall through. |
| 1415 case ObjectLiteral::Property::COMPUTED: | 1421 case ObjectLiteral::Property::COMPUTED: |
| 1416 if (key->handle()->IsSymbol()) { | 1422 if (key->handle()->IsSymbol()) { |
| 1417 if (property->emit_store()) { | 1423 if (property->emit_store()) { |
| 1418 VisitForAccumulatorValue(value); | 1424 VisitForAccumulatorValue(value); |
| 1419 __ mov(r2, Operand(key->handle())); | 1425 __ mov(r2, Operand(key->handle())); |
| 1420 __ ldr(r1, MemOperand(sp)); | 1426 __ ldr(r1, MemOperand(sp)); |
| 1421 Handle<Code> ic = is_strict_mode() | 1427 Handle<Code> ic = is_strict_mode() |
| 1422 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1428 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1423 : isolate()->builtins()->StoreIC_Initialize(); | 1429 : isolate()->builtins()->StoreIC_Initialize(); |
| 1424 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, key->id()); | 1430 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); |
| 1425 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1431 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1426 } else { | 1432 } else { |
| 1427 VisitForEffect(value); | 1433 VisitForEffect(value); |
| 1428 } | 1434 } |
| 1429 break; | 1435 break; |
| 1430 } | 1436 } |
| 1431 // Fall through. | 1437 // Fall through. |
| 1432 case ObjectLiteral::Property::PROTOTYPE: | 1438 case ObjectLiteral::Property::PROTOTYPE: |
| 1433 // Duplicate receiver on stack. | 1439 // Duplicate receiver on stack. |
| 1434 __ ldr(r0, MemOperand(sp)); | 1440 __ ldr(r0, MemOperand(sp)); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 } | 1674 } |
| 1669 } | 1675 } |
| 1670 | 1676 |
| 1671 | 1677 |
| 1672 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1678 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1673 SetSourcePosition(prop->position()); | 1679 SetSourcePosition(prop->position()); |
| 1674 Literal* key = prop->key()->AsLiteral(); | 1680 Literal* key = prop->key()->AsLiteral(); |
| 1675 __ mov(r2, Operand(key->handle())); | 1681 __ mov(r2, Operand(key->handle())); |
| 1676 // Call load IC. It has arguments receiver and property name r0 and r2. | 1682 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 1677 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1683 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1678 if (prop->is_synthetic()) { | 1684 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 1679 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | |
| 1680 } else { | |
| 1681 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id()); | |
| 1682 } | |
| 1683 } | 1685 } |
| 1684 | 1686 |
| 1685 | 1687 |
| 1686 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1688 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1687 SetSourcePosition(prop->position()); | 1689 SetSourcePosition(prop->position()); |
| 1688 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1690 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1689 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1691 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1690 if (prop->is_synthetic()) { | 1692 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 1691 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | |
| 1692 } else { | |
| 1693 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id()); | |
| 1694 } | |
| 1695 } | 1693 } |
| 1696 | 1694 |
| 1697 | 1695 |
| 1698 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1696 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1699 Token::Value op, | 1697 Token::Value op, |
| 1700 OverwriteMode mode, | 1698 OverwriteMode mode, |
| 1701 Expression* left_expr, | 1699 Expression* left_expr, |
| 1702 Expression* right_expr) { | 1700 Expression* right_expr) { |
| 1703 Label done, smi_case, stub_call; | 1701 Label done, smi_case, stub_call; |
| 1704 | 1702 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1990 // receiver into fast case. | 1988 // receiver into fast case. |
| 1991 if (expr->ends_initialization_block()) { | 1989 if (expr->ends_initialization_block()) { |
| 1992 __ ldr(r1, MemOperand(sp)); | 1990 __ ldr(r1, MemOperand(sp)); |
| 1993 } else { | 1991 } else { |
| 1994 __ pop(r1); | 1992 __ pop(r1); |
| 1995 } | 1993 } |
| 1996 | 1994 |
| 1997 Handle<Code> ic = is_strict_mode() | 1995 Handle<Code> ic = is_strict_mode() |
| 1998 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1996 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1999 : isolate()->builtins()->StoreIC_Initialize(); | 1997 : isolate()->builtins()->StoreIC_Initialize(); |
| 2000 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 1998 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2001 | 1999 |
| 2002 // If the assignment ends an initialization block, revert to fast case. | 2000 // If the assignment ends an initialization block, revert to fast case. |
| 2003 if (expr->ends_initialization_block()) { | 2001 if (expr->ends_initialization_block()) { |
| 2004 __ push(r0); // Result of assignment, saved even if not needed. | 2002 __ push(r0); // Result of assignment, saved even if not needed. |
| 2005 // Receiver is under the result value. | 2003 // Receiver is under the result value. |
| 2006 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2004 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2007 __ push(ip); | 2005 __ push(ip); |
| 2008 __ CallRuntime(Runtime::kToFastProperties, 1); | 2006 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2009 __ pop(r0); | 2007 __ pop(r0); |
| 2010 __ Drop(1); | 2008 __ Drop(1); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2036 // receiver into fast case. | 2034 // receiver into fast case. |
| 2037 if (expr->ends_initialization_block()) { | 2035 if (expr->ends_initialization_block()) { |
| 2038 __ ldr(r2, MemOperand(sp)); | 2036 __ ldr(r2, MemOperand(sp)); |
| 2039 } else { | 2037 } else { |
| 2040 __ pop(r2); | 2038 __ pop(r2); |
| 2041 } | 2039 } |
| 2042 | 2040 |
| 2043 Handle<Code> ic = is_strict_mode() | 2041 Handle<Code> ic = is_strict_mode() |
| 2044 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 2042 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 2045 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 2043 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 2046 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 2044 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2047 | 2045 |
| 2048 // If the assignment ends an initialization block, revert to fast case. | 2046 // If the assignment ends an initialization block, revert to fast case. |
| 2049 if (expr->ends_initialization_block()) { | 2047 if (expr->ends_initialization_block()) { |
| 2050 __ push(r0); // Result of assignment, saved even if not needed. | 2048 __ push(r0); // Result of assignment, saved even if not needed. |
| 2051 // Receiver is under the result value. | 2049 // Receiver is under the result value. |
| 2052 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2050 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2053 __ push(ip); | 2051 __ push(ip); |
| 2054 __ CallRuntime(Runtime::kToFastProperties, 1); | 2052 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2055 __ pop(r0); | 2053 __ pop(r0); |
| 2056 __ Drop(1); | 2054 __ Drop(1); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 VisitForStackValue(args->at(i)); | 2086 VisitForStackValue(args->at(i)); |
| 2089 } | 2087 } |
| 2090 __ mov(r2, Operand(name)); | 2088 __ mov(r2, Operand(name)); |
| 2091 } | 2089 } |
| 2092 // Record source position for debugger. | 2090 // Record source position for debugger. |
| 2093 SetSourcePosition(expr->position()); | 2091 SetSourcePosition(expr->position()); |
| 2094 // Call the IC initialization code. | 2092 // Call the IC initialization code. |
| 2095 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2093 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2096 Handle<Code> ic = | 2094 Handle<Code> ic = |
| 2097 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); | 2095 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
| 2098 unsigned ast_id = | 2096 EmitCallIC(ic, mode, expr->id()); |
| 2099 (mode == RelocInfo::CODE_TARGET_WITH_ID) ? expr->id() : kNoASTId; | |
| 2100 EmitCallIC(ic, mode, ast_id); | |
| 2101 RecordJSReturnSite(expr); | 2097 RecordJSReturnSite(expr); |
| 2102 // Restore context register. | 2098 // Restore context register. |
| 2103 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2099 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2104 context()->Plug(r0); | 2100 context()->Plug(r0); |
| 2105 } | 2101 } |
| 2106 | 2102 |
| 2107 | 2103 |
| 2108 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2104 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2109 Expression* key, | 2105 Expression* key, |
| 2110 RelocInfo::Mode mode) { | 2106 RelocInfo::Mode mode) { |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2299 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
| 2304 } else if (fun->AsProperty() != NULL) { | 2300 } else if (fun->AsProperty() != NULL) { |
| 2305 // Call to an object property. | 2301 // Call to an object property. |
| 2306 Property* prop = fun->AsProperty(); | 2302 Property* prop = fun->AsProperty(); |
| 2307 Literal* key = prop->key()->AsLiteral(); | 2303 Literal* key = prop->key()->AsLiteral(); |
| 2308 if (key != NULL && key->handle()->IsSymbol()) { | 2304 if (key != NULL && key->handle()->IsSymbol()) { |
| 2309 // Call to a named property, use call IC. | 2305 // Call to a named property, use call IC. |
| 2310 { PreservePositionScope scope(masm()->positions_recorder()); | 2306 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2311 VisitForStackValue(prop->obj()); | 2307 VisitForStackValue(prop->obj()); |
| 2312 } | 2308 } |
| 2313 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET_WITH_ID); | 2309 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
| 2314 } else { | 2310 } else { |
| 2315 // Call to a keyed property. | 2311 // Call to a keyed property. |
| 2316 // For a synthetic property use keyed load IC followed by function call, | 2312 // For a synthetic property use keyed load IC followed by function call, |
| 2317 // for a regular property use keyed EmitCallIC. | 2313 // for a regular property use keyed EmitCallIC. |
| 2318 if (prop->is_synthetic()) { | 2314 if (prop->is_synthetic()) { |
| 2319 // Do not visit the object and key subexpressions (they are shared | 2315 // Do not visit the object and key subexpressions (they are shared |
| 2320 // by all occurrences of the same rewritten parameter). | 2316 // by all occurrences of the same rewritten parameter). |
| 2321 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2317 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 2322 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2318 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
| 2323 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2319 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
| 2324 MemOperand operand = EmitSlotSearch(slot, r1); | 2320 MemOperand operand = EmitSlotSearch(slot, r1); |
| 2325 __ ldr(r1, operand); | 2321 __ ldr(r1, operand); |
| 2326 | 2322 |
| 2327 ASSERT(prop->key()->AsLiteral() != NULL); | 2323 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2328 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2324 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2329 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); | 2325 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); |
| 2330 | 2326 |
| 2331 // Record source code position for IC call. | 2327 // Record source code position for IC call. |
| 2332 SetSourcePosition(prop->position()); | 2328 SetSourcePosition(prop->position()); |
| 2333 | 2329 |
| 2334 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2330 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2335 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 2331 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 2336 __ ldr(r1, GlobalObjectOperand()); | 2332 __ ldr(r1, GlobalObjectOperand()); |
| 2337 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2333 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2338 __ Push(r0, r1); // Function, receiver. | 2334 __ Push(r0, r1); // Function, receiver. |
| 2339 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2335 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
| 2340 } else { | 2336 } else { |
| 2341 { PreservePositionScope scope(masm()->positions_recorder()); | 2337 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2342 VisitForStackValue(prop->obj()); | 2338 VisitForStackValue(prop->obj()); |
| 2343 } | 2339 } |
| 2344 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET_WITH_ID); | 2340 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
| 2345 } | 2341 } |
| 2346 } | 2342 } |
| 2347 } else { | 2343 } else { |
| 2348 { PreservePositionScope scope(masm()->positions_recorder()); | 2344 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2349 VisitForStackValue(fun); | 2345 VisitForStackValue(fun); |
| 2350 } | 2346 } |
| 2351 // Load global receiver object. | 2347 // Load global receiver object. |
| 2352 __ ldr(r1, GlobalObjectOperand()); | 2348 __ ldr(r1, GlobalObjectOperand()); |
| 2353 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2349 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2354 __ push(r1); | 2350 __ push(r1); |
| (...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3645 int arg_count = args->length(); | 3641 int arg_count = args->length(); |
| 3646 for (int i = 0; i < arg_count; i++) { | 3642 for (int i = 0; i < arg_count; i++) { |
| 3647 VisitForStackValue(args->at(i)); | 3643 VisitForStackValue(args->at(i)); |
| 3648 } | 3644 } |
| 3649 | 3645 |
| 3650 if (expr->is_jsruntime()) { | 3646 if (expr->is_jsruntime()) { |
| 3651 // Call the JS runtime function. | 3647 // Call the JS runtime function. |
| 3652 __ mov(r2, Operand(expr->name())); | 3648 __ mov(r2, Operand(expr->name())); |
| 3653 Handle<Code> ic = | 3649 Handle<Code> ic = |
| 3654 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3650 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); |
| 3655 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 3651 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3656 // Restore context register. | 3652 // Restore context register. |
| 3657 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3653 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3658 } else { | 3654 } else { |
| 3659 // Call the C runtime function. | 3655 // Call the C runtime function. |
| 3660 __ CallRuntime(expr->function(), arg_count); | 3656 __ CallRuntime(expr->function(), arg_count); |
| 3661 } | 3657 } |
| 3662 context()->Plug(r0); | 3658 context()->Plug(r0); |
| 3663 } | 3659 } |
| 3664 | 3660 |
| 3665 | 3661 |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3937 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3933 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3938 context()->Plug(r0); | 3934 context()->Plug(r0); |
| 3939 } | 3935 } |
| 3940 break; | 3936 break; |
| 3941 case NAMED_PROPERTY: { | 3937 case NAMED_PROPERTY: { |
| 3942 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3938 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 3943 __ pop(r1); | 3939 __ pop(r1); |
| 3944 Handle<Code> ic = is_strict_mode() | 3940 Handle<Code> ic = is_strict_mode() |
| 3945 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3941 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 3946 : isolate()->builtins()->StoreIC_Initialize(); | 3942 : isolate()->builtins()->StoreIC_Initialize(); |
| 3947 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 3943 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3948 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3944 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3949 if (expr->is_postfix()) { | 3945 if (expr->is_postfix()) { |
| 3950 if (!context()->IsEffect()) { | 3946 if (!context()->IsEffect()) { |
| 3951 context()->PlugTOS(); | 3947 context()->PlugTOS(); |
| 3952 } | 3948 } |
| 3953 } else { | 3949 } else { |
| 3954 context()->Plug(r0); | 3950 context()->Plug(r0); |
| 3955 } | 3951 } |
| 3956 break; | 3952 break; |
| 3957 } | 3953 } |
| 3958 case KEYED_PROPERTY: { | 3954 case KEYED_PROPERTY: { |
| 3959 __ pop(r1); // Key. | 3955 __ pop(r1); // Key. |
| 3960 __ pop(r2); // Receiver. | 3956 __ pop(r2); // Receiver. |
| 3961 Handle<Code> ic = is_strict_mode() | 3957 Handle<Code> ic = is_strict_mode() |
| 3962 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3958 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 3963 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3959 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 3964 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 3960 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3965 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3961 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3966 if (expr->is_postfix()) { | 3962 if (expr->is_postfix()) { |
| 3967 if (!context()->IsEffect()) { | 3963 if (!context()->IsEffect()) { |
| 3968 context()->PlugTOS(); | 3964 context()->PlugTOS(); |
| 3969 } | 3965 } |
| 3970 } else { | 3966 } else { |
| 3971 context()->Plug(r0); | 3967 context()->Plug(r0); |
| 3972 } | 3968 } |
| 3973 break; | 3969 break; |
| 3974 } | 3970 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4249 | 4245 |
| 4250 Register FullCodeGenerator::context_register() { | 4246 Register FullCodeGenerator::context_register() { |
| 4251 return cp; | 4247 return cp; |
| 4252 } | 4248 } |
| 4253 | 4249 |
| 4254 | 4250 |
| 4255 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | 4251 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, |
| 4256 RelocInfo::Mode mode, | 4252 RelocInfo::Mode mode, |
| 4257 unsigned ast_id) { | 4253 unsigned ast_id) { |
| 4258 ASSERT(mode == RelocInfo::CODE_TARGET || | 4254 ASSERT(mode == RelocInfo::CODE_TARGET || |
| 4259 mode == RelocInfo::CODE_TARGET_CONTEXT || | 4255 mode == RelocInfo::CODE_TARGET_CONTEXT); |
| 4260 mode == RelocInfo::CODE_TARGET_WITH_ID); | |
| 4261 Counters* counters = isolate()->counters(); | 4256 Counters* counters = isolate()->counters(); |
| 4262 switch (ic->kind()) { | 4257 switch (ic->kind()) { |
| 4263 case Code::LOAD_IC: | 4258 case Code::LOAD_IC: |
| 4264 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); | 4259 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); |
| 4265 break; | 4260 break; |
| 4266 case Code::KEYED_LOAD_IC: | 4261 case Code::KEYED_LOAD_IC: |
| 4267 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); | 4262 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); |
| 4268 break; | 4263 break; |
| 4269 case Code::STORE_IC: | 4264 case Code::STORE_IC: |
| 4270 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); | 4265 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); |
| 4271 break; | 4266 break; |
| 4272 case Code::KEYED_STORE_IC: | 4267 case Code::KEYED_STORE_IC: |
| 4273 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); | 4268 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); |
| 4274 default: | 4269 default: |
| 4275 break; | 4270 break; |
| 4276 } | 4271 } |
| 4277 if (mode == RelocInfo::CODE_TARGET_WITH_ID) { | 4272 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { |
| 4278 ASSERT(ast_id != kNoASTId); | 4273 __ Call(ic, mode); |
| 4274 } else { |
| 4275 ASSERT(mode == RelocInfo::CODE_TARGET); |
| 4276 mode = RelocInfo::CODE_TARGET_WITH_ID; |
| 4279 __ CallWithAstId(ic, mode, ast_id); | 4277 __ CallWithAstId(ic, mode, ast_id); |
| 4280 } else { | |
| 4281 ASSERT(ast_id == kNoASTId); | |
| 4282 __ Call(ic, mode); | |
| 4283 } | 4278 } |
| 4284 } | 4279 } |
| 4285 | 4280 |
| 4286 | 4281 |
| 4287 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | 4282 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, |
| 4288 JumpPatchSite* patch_site, | 4283 JumpPatchSite* patch_site, |
| 4289 unsigned ast_id) { | 4284 unsigned ast_id) { |
| 4290 Counters* counters = isolate()->counters(); | 4285 Counters* counters = isolate()->counters(); |
| 4291 switch (ic->kind()) { | 4286 switch (ic->kind()) { |
| 4292 case Code::LOAD_IC: | 4287 case Code::LOAD_IC: |
| 4293 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); | 4288 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); |
| 4294 break; | 4289 break; |
| 4295 case Code::KEYED_LOAD_IC: | 4290 case Code::KEYED_LOAD_IC: |
| 4296 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); | 4291 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); |
| 4297 break; | 4292 break; |
| 4298 case Code::STORE_IC: | 4293 case Code::STORE_IC: |
| 4299 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); | 4294 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); |
| 4300 break; | 4295 break; |
| 4301 case Code::KEYED_STORE_IC: | 4296 case Code::KEYED_STORE_IC: |
| 4302 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); | 4297 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); |
| 4303 default: | 4298 default: |
| 4304 break; | 4299 break; |
| 4305 } | 4300 } |
| 4306 | 4301 |
| 4307 if (ast_id != kNoASTId) { | 4302 if (ast_id == kNoASTId) { |
| 4303 __ Call(ic, RelocInfo::CODE_TARGET); |
| 4304 } else { |
| 4308 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); | 4305 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); |
| 4309 } else { | |
| 4310 __ Call(ic, RelocInfo::CODE_TARGET); | |
| 4311 } | 4306 } |
| 4312 if (patch_site != NULL && patch_site->is_bound()) { | 4307 if (patch_site != NULL && patch_site->is_bound()) { |
| 4313 patch_site->EmitPatchInfo(); | 4308 patch_site->EmitPatchInfo(); |
| 4314 } else { | 4309 } else { |
| 4315 __ nop(); // Signals no inlined code. | 4310 __ nop(); // Signals no inlined code. |
| 4316 } | 4311 } |
| 4317 } | 4312 } |
| 4318 | 4313 |
| 4319 | 4314 |
| 4320 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4315 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4354 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4349 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 4355 __ add(pc, r1, Operand(masm_->CodeObject())); | 4350 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 4356 } | 4351 } |
| 4357 | 4352 |
| 4358 | 4353 |
| 4359 #undef __ | 4354 #undef __ |
| 4360 | 4355 |
| 4361 } } // namespace v8::internal | 4356 } } // namespace v8::internal |
| 4362 | 4357 |
| 4363 #endif // V8_TARGET_ARCH_ARM | 4358 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |