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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "scopes.h" | 46 #include "scopes.h" |
47 #include "stub-cache.h" | 47 #include "stub-cache.h" |
48 | 48 |
49 #include "mips/code-stubs-mips.h" | 49 #include "mips/code-stubs-mips.h" |
50 | 50 |
51 namespace v8 { | 51 namespace v8 { |
52 namespace internal { | 52 namespace internal { |
53 | 53 |
54 #define __ ACCESS_MASM(masm_) | 54 #define __ ACCESS_MASM(masm_) |
55 | 55 |
| 56 static unsigned GetPropertyId(Property* property) { |
| 57 if (property->is_synthetic()) return AstNode::kNoNumber; |
| 58 return property->id(); |
| 59 } |
| 60 |
56 | 61 |
57 // A patch site is a location in the code which it is possible to patch. This | 62 // A patch site is a location in the code which it is possible to patch. This |
58 // class has a number of methods to emit the code which is patchable and the | 63 // class has a number of methods to emit the code which is patchable and the |
59 // method EmitPatchInfo to record a marker back to the patchable code. This | 64 // method EmitPatchInfo to record a marker back to the patchable code. This |
60 // marker is a andi at, rx, #yyy instruction, and x * 0x0000ffff + yyy (raw 16 | 65 // marker is a andi at, rx, #yyy instruction, and x * 0x0000ffff + yyy (raw 16 |
61 // bit immediate value is used) is the delta from the pc to the first | 66 // bit immediate value is used) is the delta from the pc to the first |
62 // instruction of the patchable code. | 67 // instruction of the patchable code. |
63 class JumpPatchSite BASE_EMBEDDED { | 68 class JumpPatchSite BASE_EMBEDDED { |
64 public: | 69 public: |
65 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { | 70 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 __ Drop(1); // Switch value is no longer needed. | 845 __ Drop(1); // Switch value is no longer needed. |
841 __ Branch(clause->body_target()); | 846 __ Branch(clause->body_target()); |
842 | 847 |
843 __ bind(&slow_case); | 848 __ bind(&slow_case); |
844 } | 849 } |
845 | 850 |
846 // Record position before stub call for type feedback. | 851 // Record position before stub call for type feedback. |
847 SetSourcePosition(clause->position()); | 852 SetSourcePosition(clause->position()); |
848 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 853 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
849 EmitCallIC(ic, &patch_site, clause->CompareId()); | 854 EmitCallIC(ic, &patch_site, clause->CompareId()); |
| 855 |
850 __ Branch(&next_test, ne, v0, Operand(zero_reg)); | 856 __ Branch(&next_test, ne, v0, Operand(zero_reg)); |
851 __ Drop(1); // Switch value is no longer needed. | 857 __ Drop(1); // Switch value is no longer needed. |
852 __ Branch(clause->body_target()); | 858 __ Branch(clause->body_target()); |
853 } | 859 } |
854 | 860 |
855 // Discard the test value and jump to the default if present, otherwise to | 861 // Discard the test value and jump to the default if present, otherwise to |
856 // the end of the statement. | 862 // the end of the statement. |
857 __ bind(&next_test); | 863 __ bind(&next_test); |
858 __ Drop(1); // Switch value is no longer needed. | 864 __ Drop(1); // Switch value is no longer needed. |
859 if (default_clause == NULL) { | 865 if (default_clause == NULL) { |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 key_literal->handle()->IsSmi()) { | 1226 key_literal->handle()->IsSmi()) { |
1221 // Load arguments object if there are no eval-introduced | 1227 // Load arguments object if there are no eval-introduced |
1222 // variables. Then load the argument from the arguments | 1228 // variables. Then load the argument from the arguments |
1223 // object using keyed load. | 1229 // object using keyed load. |
1224 __ lw(a1, | 1230 __ lw(a1, |
1225 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1231 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
1226 slow)); | 1232 slow)); |
1227 __ li(a0, Operand(key_literal->handle())); | 1233 __ li(a0, Operand(key_literal->handle())); |
1228 Handle<Code> ic = | 1234 Handle<Code> ic = |
1229 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1235 isolate()->builtins()->KeyedLoadIC_Initialize(); |
1230 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1236 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
1231 __ Branch(done); | 1237 __ Branch(done); |
1232 } | 1238 } |
1233 } | 1239 } |
1234 } | 1240 } |
1235 } | 1241 } |
1236 } | 1242 } |
1237 | 1243 |
1238 | 1244 |
1239 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1245 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1240 // Four cases: non-this global variables, lookup slots, all other | 1246 // Four cases: non-this global variables, lookup slots, all other |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 // Assert that the key is a smi. | 1308 // Assert that the key is a smi. |
1303 Literal* key_literal = property->key()->AsLiteral(); | 1309 Literal* key_literal = property->key()->AsLiteral(); |
1304 ASSERT_NOT_NULL(key_literal); | 1310 ASSERT_NOT_NULL(key_literal); |
1305 ASSERT(key_literal->handle()->IsSmi()); | 1311 ASSERT(key_literal->handle()->IsSmi()); |
1306 | 1312 |
1307 // Load the key. | 1313 // Load the key. |
1308 __ li(a0, Operand(key_literal->handle())); | 1314 __ li(a0, Operand(key_literal->handle())); |
1309 | 1315 |
1310 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 1316 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
1311 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1317 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1312 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1318 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
1313 context()->Plug(v0); | 1319 context()->Plug(v0); |
1314 } | 1320 } |
1315 } | 1321 } |
1316 | 1322 |
1317 | 1323 |
1318 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1324 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1319 Comment cmnt(masm_, "[ RegExpLiteral"); | 1325 Comment cmnt(masm_, "[ RegExpLiteral"); |
1320 Label materialized; | 1326 Label materialized; |
1321 // Registers will be used as follows: | 1327 // Registers will be used as follows: |
1322 // t1 = materialized value (RegExp literal) | 1328 // t1 = materialized value (RegExp literal) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 case ObjectLiteral::Property::COMPUTED: | 1420 case ObjectLiteral::Property::COMPUTED: |
1415 if (key->handle()->IsSymbol()) { | 1421 if (key->handle()->IsSymbol()) { |
1416 if (property->emit_store()) { | 1422 if (property->emit_store()) { |
1417 VisitForAccumulatorValue(value); | 1423 VisitForAccumulatorValue(value); |
1418 __ mov(a0, result_register()); | 1424 __ mov(a0, result_register()); |
1419 __ li(a2, Operand(key->handle())); | 1425 __ li(a2, Operand(key->handle())); |
1420 __ lw(a1, MemOperand(sp)); | 1426 __ lw(a1, 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 __ lw(a0, MemOperand(sp)); | 1440 __ lw(a0, MemOperand(sp)); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1672 } | 1678 } |
1673 | 1679 |
1674 | 1680 |
1675 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1681 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1676 SetSourcePosition(prop->position()); | 1682 SetSourcePosition(prop->position()); |
1677 Literal* key = prop->key()->AsLiteral(); | 1683 Literal* key = prop->key()->AsLiteral(); |
1678 __ mov(a0, result_register()); | 1684 __ mov(a0, result_register()); |
1679 __ li(a2, Operand(key->handle())); | 1685 __ li(a2, Operand(key->handle())); |
1680 // Call load IC. It has arguments receiver and property name a0 and a2. | 1686 // Call load IC. It has arguments receiver and property name a0 and a2. |
1681 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1687 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1682 if (prop->is_synthetic()) { | 1688 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1683 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | |
1684 } else { | |
1685 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id()); | |
1686 } | |
1687 } | 1689 } |
1688 | 1690 |
1689 | 1691 |
1690 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1692 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1691 SetSourcePosition(prop->position()); | 1693 SetSourcePosition(prop->position()); |
1692 __ mov(a0, result_register()); | 1694 __ mov(a0, result_register()); |
1693 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 1695 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
1694 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1696 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1695 if (prop->is_synthetic()) { | 1697 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
1696 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | |
1697 } else { | |
1698 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id()); | |
1699 } | |
1700 } | 1698 } |
1701 | 1699 |
1702 | 1700 |
1703 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1701 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1704 Token::Value op, | 1702 Token::Value op, |
1705 OverwriteMode mode, | 1703 OverwriteMode mode, |
1706 Expression* left_expr, | 1704 Expression* left_expr, |
1707 Expression* right_expr) { | 1705 Expression* right_expr) { |
1708 Label done, smi_case, stub_call; | 1706 Label done, smi_case, stub_call; |
1709 | 1707 |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 // receiver into fast case. | 1994 // receiver into fast case. |
1997 if (expr->ends_initialization_block()) { | 1995 if (expr->ends_initialization_block()) { |
1998 __ lw(a1, MemOperand(sp)); | 1996 __ lw(a1, MemOperand(sp)); |
1999 } else { | 1997 } else { |
2000 __ pop(a1); | 1998 __ pop(a1); |
2001 } | 1999 } |
2002 | 2000 |
2003 Handle<Code> ic = is_strict_mode() | 2001 Handle<Code> ic = is_strict_mode() |
2004 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2002 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
2005 : isolate()->builtins()->StoreIC_Initialize(); | 2003 : isolate()->builtins()->StoreIC_Initialize(); |
2006 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 2004 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
2007 | 2005 |
2008 // If the assignment ends an initialization block, revert to fast case. | 2006 // If the assignment ends an initialization block, revert to fast case. |
2009 if (expr->ends_initialization_block()) { | 2007 if (expr->ends_initialization_block()) { |
2010 __ push(v0); // Result of assignment, saved even if not needed. | 2008 __ push(v0); // Result of assignment, saved even if not needed. |
2011 // Receiver is under the result value. | 2009 // Receiver is under the result value. |
2012 __ lw(t0, MemOperand(sp, kPointerSize)); | 2010 __ lw(t0, MemOperand(sp, kPointerSize)); |
2013 __ push(t0); | 2011 __ push(t0); |
2014 __ CallRuntime(Runtime::kToFastProperties, 1); | 2012 __ CallRuntime(Runtime::kToFastProperties, 1); |
2015 __ pop(v0); | 2013 __ pop(v0); |
2016 __ Drop(1); | 2014 __ Drop(1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2048 // receiver into fast case. | 2046 // receiver into fast case. |
2049 if (expr->ends_initialization_block()) { | 2047 if (expr->ends_initialization_block()) { |
2050 __ lw(a2, MemOperand(sp)); | 2048 __ lw(a2, MemOperand(sp)); |
2051 } else { | 2049 } else { |
2052 __ pop(a2); | 2050 __ pop(a2); |
2053 } | 2051 } |
2054 | 2052 |
2055 Handle<Code> ic = is_strict_mode() | 2053 Handle<Code> ic = is_strict_mode() |
2056 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 2054 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
2057 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 2055 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
2058 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 2056 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
2059 | 2057 |
2060 // If the assignment ends an initialization block, revert to fast case. | 2058 // If the assignment ends an initialization block, revert to fast case. |
2061 if (expr->ends_initialization_block()) { | 2059 if (expr->ends_initialization_block()) { |
2062 __ push(v0); // Result of assignment, saved even if not needed. | 2060 __ push(v0); // Result of assignment, saved even if not needed. |
2063 // Receiver is under the result value. | 2061 // Receiver is under the result value. |
2064 __ lw(t0, MemOperand(sp, kPointerSize)); | 2062 __ lw(t0, MemOperand(sp, kPointerSize)); |
2065 __ push(t0); | 2063 __ push(t0); |
2066 __ CallRuntime(Runtime::kToFastProperties, 1); | 2064 __ CallRuntime(Runtime::kToFastProperties, 1); |
2067 __ pop(v0); | 2065 __ pop(v0); |
2068 __ Drop(1); | 2066 __ Drop(1); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2101 VisitForStackValue(args->at(i)); | 2099 VisitForStackValue(args->at(i)); |
2102 } | 2100 } |
2103 __ li(a2, Operand(name)); | 2101 __ li(a2, Operand(name)); |
2104 } | 2102 } |
2105 // Record source position for debugger. | 2103 // Record source position for debugger. |
2106 SetSourcePosition(expr->position()); | 2104 SetSourcePosition(expr->position()); |
2107 // Call the IC initialization code. | 2105 // Call the IC initialization code. |
2108 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2106 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2109 Handle<Code> ic = | 2107 Handle<Code> ic = |
2110 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); | 2108 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
2111 unsigned ast_id = | 2109 EmitCallIC(ic, mode, expr->id()); |
2112 (mode == RelocInfo::CODE_TARGET_WITH_ID) ? expr->id() : kNoASTId; | |
2113 EmitCallIC(ic, mode, ast_id); | |
2114 RecordJSReturnSite(expr); | 2110 RecordJSReturnSite(expr); |
2115 // Restore context register. | 2111 // Restore context register. |
2116 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2112 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2117 context()->Plug(v0); | 2113 context()->Plug(v0); |
2118 } | 2114 } |
2119 | 2115 |
2120 | 2116 |
2121 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2117 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2122 Expression* key, | 2118 Expression* key, |
2123 RelocInfo::Mode mode) { | 2119 RelocInfo::Mode mode) { |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2314 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2310 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2315 } else if (fun->AsProperty() != NULL) { | 2311 } else if (fun->AsProperty() != NULL) { |
2316 // Call to an object property. | 2312 // Call to an object property. |
2317 Property* prop = fun->AsProperty(); | 2313 Property* prop = fun->AsProperty(); |
2318 Literal* key = prop->key()->AsLiteral(); | 2314 Literal* key = prop->key()->AsLiteral(); |
2319 if (key != NULL && key->handle()->IsSymbol()) { | 2315 if (key != NULL && key->handle()->IsSymbol()) { |
2320 // Call to a named property, use call IC. | 2316 // Call to a named property, use call IC. |
2321 { PreservePositionScope scope(masm()->positions_recorder()); | 2317 { PreservePositionScope scope(masm()->positions_recorder()); |
2322 VisitForStackValue(prop->obj()); | 2318 VisitForStackValue(prop->obj()); |
2323 } | 2319 } |
2324 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET_WITH_ID); | 2320 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
2325 } else { | 2321 } else { |
2326 // Call to a keyed property. | 2322 // Call to a keyed property. |
2327 // For a synthetic property use keyed load IC followed by function call, | 2323 // For a synthetic property use keyed load IC followed by function call, |
2328 // for a regular property use keyed EmitCallIC. | 2324 // for a regular property use keyed EmitCallIC. |
2329 if (prop->is_synthetic()) { | 2325 if (prop->is_synthetic()) { |
2330 // Do not visit the object and key subexpressions (they are shared | 2326 // Do not visit the object and key subexpressions (they are shared |
2331 // by all occurrences of the same rewritten parameter). | 2327 // by all occurrences of the same rewritten parameter). |
2332 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2328 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
2333 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2329 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
2334 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2330 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
2335 MemOperand operand = EmitSlotSearch(slot, a1); | 2331 MemOperand operand = EmitSlotSearch(slot, a1); |
2336 __ lw(a1, operand); | 2332 __ lw(a1, operand); |
2337 | 2333 |
2338 ASSERT(prop->key()->AsLiteral() != NULL); | 2334 ASSERT(prop->key()->AsLiteral() != NULL); |
2339 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2335 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2340 __ li(a0, Operand(prop->key()->AsLiteral()->handle())); | 2336 __ li(a0, Operand(prop->key()->AsLiteral()->handle())); |
2341 | 2337 |
2342 // Record source code position for IC call. | 2338 // Record source code position for IC call. |
2343 SetSourcePosition(prop->position()); | 2339 SetSourcePosition(prop->position()); |
2344 | 2340 |
2345 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2341 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2346 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 2342 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
2347 __ lw(a1, GlobalObjectOperand()); | 2343 __ lw(a1, GlobalObjectOperand()); |
2348 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2344 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
2349 __ Push(v0, a1); // Function, receiver. | 2345 __ Push(v0, a1); // Function, receiver. |
2350 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2346 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
2351 } else { | 2347 } else { |
2352 { PreservePositionScope scope(masm()->positions_recorder()); | 2348 { PreservePositionScope scope(masm()->positions_recorder()); |
2353 VisitForStackValue(prop->obj()); | 2349 VisitForStackValue(prop->obj()); |
2354 } | 2350 } |
2355 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET_WITH_ID); | 2351 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
2356 } | 2352 } |
2357 } | 2353 } |
2358 } else { | 2354 } else { |
2359 { PreservePositionScope scope(masm()->positions_recorder()); | 2355 { PreservePositionScope scope(masm()->positions_recorder()); |
2360 VisitForStackValue(fun); | 2356 VisitForStackValue(fun); |
2361 } | 2357 } |
2362 // Load global receiver object. | 2358 // Load global receiver object. |
2363 __ lw(a1, GlobalObjectOperand()); | 2359 __ lw(a1, GlobalObjectOperand()); |
2364 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2360 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
2365 __ push(a1); | 2361 __ push(a1); |
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3662 int arg_count = args->length(); | 3658 int arg_count = args->length(); |
3663 for (int i = 0; i < arg_count; i++) { | 3659 for (int i = 0; i < arg_count; i++) { |
3664 VisitForStackValue(args->at(i)); | 3660 VisitForStackValue(args->at(i)); |
3665 } | 3661 } |
3666 | 3662 |
3667 if (expr->is_jsruntime()) { | 3663 if (expr->is_jsruntime()) { |
3668 // Call the JS runtime function. | 3664 // Call the JS runtime function. |
3669 __ li(a2, Operand(expr->name())); | 3665 __ li(a2, Operand(expr->name())); |
3670 Handle<Code> ic = | 3666 Handle<Code> ic = |
3671 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3667 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); |
3672 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 3668 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
3673 // Restore context register. | 3669 // Restore context register. |
3674 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3670 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3675 } else { | 3671 } else { |
3676 // Call the C runtime function. | 3672 // Call the C runtime function. |
3677 __ CallRuntime(expr->function(), arg_count); | 3673 __ CallRuntime(expr->function(), arg_count); |
3678 } | 3674 } |
3679 context()->Plug(v0); | 3675 context()->Plug(v0); |
3680 } | 3676 } |
3681 | 3677 |
3682 | 3678 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3955 context()->Plug(v0); | 3951 context()->Plug(v0); |
3956 } | 3952 } |
3957 break; | 3953 break; |
3958 case NAMED_PROPERTY: { | 3954 case NAMED_PROPERTY: { |
3959 __ mov(a0, result_register()); // Value. | 3955 __ mov(a0, result_register()); // Value. |
3960 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. | 3956 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); // Name. |
3961 __ pop(a1); // Receiver. | 3957 __ pop(a1); // Receiver. |
3962 Handle<Code> ic = is_strict_mode() | 3958 Handle<Code> ic = is_strict_mode() |
3963 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3959 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
3964 : isolate()->builtins()->StoreIC_Initialize(); | 3960 : isolate()->builtins()->StoreIC_Initialize(); |
3965 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 3961 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
3966 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3962 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3967 if (expr->is_postfix()) { | 3963 if (expr->is_postfix()) { |
3968 if (!context()->IsEffect()) { | 3964 if (!context()->IsEffect()) { |
3969 context()->PlugTOS(); | 3965 context()->PlugTOS(); |
3970 } | 3966 } |
3971 } else { | 3967 } else { |
3972 context()->Plug(v0); | 3968 context()->Plug(v0); |
3973 } | 3969 } |
3974 break; | 3970 break; |
3975 } | 3971 } |
3976 case KEYED_PROPERTY: { | 3972 case KEYED_PROPERTY: { |
3977 __ mov(a0, result_register()); // Value. | 3973 __ mov(a0, result_register()); // Value. |
3978 __ pop(a1); // Key. | 3974 __ pop(a1); // Key. |
3979 __ pop(a2); // Receiver. | 3975 __ pop(a2); // Receiver. |
3980 Handle<Code> ic = is_strict_mode() | 3976 Handle<Code> ic = is_strict_mode() |
3981 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3977 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
3982 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3978 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
3983 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); | 3979 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); |
3984 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3980 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3985 if (expr->is_postfix()) { | 3981 if (expr->is_postfix()) { |
3986 if (!context()->IsEffect()) { | 3982 if (!context()->IsEffect()) { |
3987 context()->PlugTOS(); | 3983 context()->PlugTOS(); |
3988 } | 3984 } |
3989 } else { | 3985 } else { |
3990 context()->Plug(v0); | 3986 context()->Plug(v0); |
3991 } | 3987 } |
3992 break; | 3988 break; |
3993 } | 3989 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4262 | 4258 |
4263 Register FullCodeGenerator::context_register() { | 4259 Register FullCodeGenerator::context_register() { |
4264 return cp; | 4260 return cp; |
4265 } | 4261 } |
4266 | 4262 |
4267 | 4263 |
4268 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | 4264 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, |
4269 RelocInfo::Mode mode, | 4265 RelocInfo::Mode mode, |
4270 unsigned ast_id) { | 4266 unsigned ast_id) { |
4271 ASSERT(mode == RelocInfo::CODE_TARGET || | 4267 ASSERT(mode == RelocInfo::CODE_TARGET || |
4272 mode == RelocInfo::CODE_TARGET_CONTEXT || | 4268 mode == RelocInfo::CODE_TARGET_CONTEXT); |
4273 mode == RelocInfo::CODE_TARGET_WITH_ID); | |
4274 Counters* counters = isolate()->counters(); | 4269 Counters* counters = isolate()->counters(); |
4275 switch (ic->kind()) { | 4270 switch (ic->kind()) { |
4276 case Code::LOAD_IC: | 4271 case Code::LOAD_IC: |
4277 __ IncrementCounter(counters->named_load_full(), 1, a1, a2); | 4272 __ IncrementCounter(counters->named_load_full(), 1, a1, a2); |
4278 break; | 4273 break; |
4279 case Code::KEYED_LOAD_IC: | 4274 case Code::KEYED_LOAD_IC: |
4280 __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2); | 4275 __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2); |
4281 break; | 4276 break; |
4282 case Code::STORE_IC: | 4277 case Code::STORE_IC: |
4283 __ IncrementCounter(counters->named_store_full(), 1, a1, a2); | 4278 __ IncrementCounter(counters->named_store_full(), 1, a1, a2); |
4284 break; | 4279 break; |
4285 case Code::KEYED_STORE_IC: | 4280 case Code::KEYED_STORE_IC: |
4286 __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2); | 4281 __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2); |
4287 default: | 4282 default: |
4288 break; | 4283 break; |
4289 } | 4284 } |
4290 if (mode == RelocInfo::CODE_TARGET_WITH_ID) { | 4285 if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) { |
4291 ASSERT(ast_id != kNoASTId); | 4286 __ Call(ic, mode); |
| 4287 } else { |
| 4288 ASSERT(mode == RelocInfo::CODE_TARGET); |
| 4289 mode = RelocInfo::CODE_TARGET_WITH_ID; |
4292 __ CallWithAstId(ic, mode, ast_id); | 4290 __ CallWithAstId(ic, mode, ast_id); |
4293 } else { | |
4294 ASSERT(ast_id == kNoASTId); | |
4295 __ Call(ic, mode); | |
4296 } | 4291 } |
4297 } | 4292 } |
4298 | 4293 |
4299 | 4294 |
4300 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | 4295 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, |
4301 JumpPatchSite* patch_site, | 4296 JumpPatchSite* patch_site, |
4302 unsigned ast_id) { | 4297 unsigned ast_id) { |
4303 Counters* counters = isolate()->counters(); | 4298 Counters* counters = isolate()->counters(); |
4304 switch (ic->kind()) { | 4299 switch (ic->kind()) { |
4305 case Code::LOAD_IC: | 4300 case Code::LOAD_IC: |
4306 __ IncrementCounter(counters->named_load_full(), 1, a1, a2); | 4301 __ IncrementCounter(counters->named_load_full(), 1, a1, a2); |
4307 break; | 4302 break; |
4308 case Code::KEYED_LOAD_IC: | 4303 case Code::KEYED_LOAD_IC: |
4309 __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2); | 4304 __ IncrementCounter(counters->keyed_load_full(), 1, a1, a2); |
4310 break; | 4305 break; |
4311 case Code::STORE_IC: | 4306 case Code::STORE_IC: |
4312 __ IncrementCounter(counters->named_store_full(), 1, a1, a2); | 4307 __ IncrementCounter(counters->named_store_full(), 1, a1, a2); |
4313 break; | 4308 break; |
4314 case Code::KEYED_STORE_IC: | 4309 case Code::KEYED_STORE_IC: |
4315 __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2); | 4310 __ IncrementCounter(counters->keyed_store_full(), 1, a1, a2); |
4316 default: | 4311 default: |
4317 break; | 4312 break; |
4318 } | 4313 } |
4319 | 4314 |
4320 if (ast_id != kNoASTId) { | 4315 if (ast_id == kNoASTId) { |
| 4316 __ Call(ic, RelocInfo::CODE_TARGET); |
| 4317 } else { |
4321 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); | 4318 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); |
4322 } else { | |
4323 __ Call(ic, RelocInfo::CODE_TARGET); | |
4324 } | 4319 } |
4325 if (patch_site != NULL && patch_site->is_bound()) { | 4320 if (patch_site != NULL && patch_site->is_bound()) { |
4326 patch_site->EmitPatchInfo(); | 4321 patch_site->EmitPatchInfo(); |
4327 } else { | 4322 } else { |
4328 __ nop(); // Signals no inlined code. | 4323 __ nop(); // Signals no inlined code. |
4329 } | 4324 } |
4330 } | 4325 } |
4331 | 4326 |
4332 | 4327 |
4333 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4328 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4368 __ Addu(at, a1, Operand(masm_->CodeObject())); | 4363 __ Addu(at, a1, Operand(masm_->CodeObject())); |
4369 __ Jump(at); | 4364 __ Jump(at); |
4370 } | 4365 } |
4371 | 4366 |
4372 | 4367 |
4373 #undef __ | 4368 #undef __ |
4374 | 4369 |
4375 } } // namespace v8::internal | 4370 } } // namespace v8::internal |
4376 | 4371 |
4377 #endif // V8_TARGET_ARCH_MIPS | 4372 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |