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