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