| 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 // Bail out if the receiver has a named interceptor or requires access checks. | 119 // Bail out if the receiver has a named interceptor or requires access checks. |
| 120 Register map = scratch1; | 120 Register map = scratch1; |
| 121 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 121 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 122 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); | 122 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 123 __ And(at, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); | 123 __ And(at, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); |
| 124 __ Branch(miss_label, ne, at, Operand(zero_reg)); | 124 __ Branch(miss_label, ne, at, Operand(zero_reg)); |
| 125 | 125 |
| 126 | 126 |
| 127 // Check that receiver is a JSObject. | 127 // Check that receiver is a JSObject. |
| 128 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 128 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
| 129 __ Branch(miss_label, lt, scratch0, Operand(FIRST_JS_OBJECT_TYPE)); | 129 __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 130 | 130 |
| 131 // Load properties array. | 131 // Load properties array. |
| 132 Register properties = scratch0; | 132 Register properties = scratch0; |
| 133 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 133 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 134 // Check that the properties array is a dictionary. | 134 // Check that the properties array is a dictionary. |
| 135 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 135 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
| 136 Register tmp = properties; | 136 Register tmp = properties; |
| 137 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 137 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
| 138 __ Branch(miss_label, ne, map, Operand(tmp)); | 138 __ Branch(miss_label, ne, map, Operand(tmp)); |
| 139 | 139 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 } | 465 } |
| 466 | 466 |
| 467 Handle<Code> ic(code); | 467 Handle<Code> ic(code); |
| 468 __ Jump(ic, RelocInfo::CODE_TARGET); | 468 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 469 } | 469 } |
| 470 | 470 |
| 471 | 471 |
| 472 static void GenerateCallFunction(MacroAssembler* masm, | 472 static void GenerateCallFunction(MacroAssembler* masm, |
| 473 Object* object, | 473 Object* object, |
| 474 const ParameterCount& arguments, | 474 const ParameterCount& arguments, |
| 475 Label* miss) { | 475 Label* miss, |
| 476 Code::ExtraICState extra_ic_state) { |
| 476 // ----------- S t a t e ------------- | 477 // ----------- S t a t e ------------- |
| 477 // -- a0: receiver | 478 // -- a0: receiver |
| 478 // -- a1: function to call | 479 // -- a1: function to call |
| 479 // ----------------------------------- | 480 // ----------------------------------- |
| 480 // Check that the function really is a function. | 481 // Check that the function really is a function. |
| 481 __ JumpIfSmi(a1, miss); | 482 __ JumpIfSmi(a1, miss); |
| 482 __ GetObjectType(a1, a3, a3); | 483 __ GetObjectType(a1, a3, a3); |
| 483 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE)); | 484 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE)); |
| 484 | 485 |
| 485 // Patch the receiver on the stack with the global proxy if | 486 // Patch the receiver on the stack with the global proxy if |
| 486 // necessary. | 487 // necessary. |
| 487 if (object->IsGlobalObject()) { | 488 if (object->IsGlobalObject()) { |
| 488 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 489 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); |
| 489 __ sw(a3, MemOperand(sp, arguments.immediate() * kPointerSize)); | 490 __ sw(a3, MemOperand(sp, arguments.immediate() * kPointerSize)); |
| 490 } | 491 } |
| 491 | 492 |
| 492 // Invoke the function. | 493 // Invoke the function. |
| 493 __ InvokeFunction(a1, arguments, JUMP_FUNCTION); | 494 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) |
| 495 ? CALL_AS_FUNCTION |
| 496 : CALL_AS_METHOD; |
| 497 __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 494 } | 498 } |
| 495 | 499 |
| 496 | 500 |
| 497 static void PushInterceptorArguments(MacroAssembler* masm, | 501 static void PushInterceptorArguments(MacroAssembler* masm, |
| 498 Register receiver, | 502 Register receiver, |
| 499 Register holder, | 503 Register holder, |
| 500 Register name, | 504 Register name, |
| 501 JSObject* holder_obj) { | 505 JSObject* holder_obj) { |
| 502 __ push(name); | 506 __ push(name); |
| 503 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); | 507 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 ExternalReference(&fun, | 626 ExternalReference(&fun, |
| 623 ExternalReference::DIRECT_API_CALL, | 627 ExternalReference::DIRECT_API_CALL, |
| 624 masm->isolate()); | 628 masm->isolate()); |
| 625 return masm->TryCallApiFunctionAndReturn(ref, kStackUnwindSpace); | 629 return masm->TryCallApiFunctionAndReturn(ref, kStackUnwindSpace); |
| 626 } | 630 } |
| 627 | 631 |
| 628 class CallInterceptorCompiler BASE_EMBEDDED { | 632 class CallInterceptorCompiler BASE_EMBEDDED { |
| 629 public: | 633 public: |
| 630 CallInterceptorCompiler(StubCompiler* stub_compiler, | 634 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| 631 const ParameterCount& arguments, | 635 const ParameterCount& arguments, |
| 632 Register name) | 636 Register name, |
| 637 Code::ExtraICState extra_ic_state) |
| 633 : stub_compiler_(stub_compiler), | 638 : stub_compiler_(stub_compiler), |
| 634 arguments_(arguments), | 639 arguments_(arguments), |
| 635 name_(name) {} | 640 name_(name), |
| 641 extra_ic_state_(extra_ic_state) {} |
| 636 | 642 |
| 637 MaybeObject* Compile(MacroAssembler* masm, | 643 MaybeObject* Compile(MacroAssembler* masm, |
| 638 JSObject* object, | 644 JSObject* object, |
| 639 JSObject* holder, | 645 JSObject* holder, |
| 640 String* name, | 646 String* name, |
| 641 LookupResult* lookup, | 647 LookupResult* lookup, |
| 642 Register receiver, | 648 Register receiver, |
| 643 Register scratch1, | 649 Register scratch1, |
| 644 Register scratch2, | 650 Register scratch2, |
| 645 Register scratch3, | 651 Register scratch3, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 ASSERT(depth2 == kInvalidProtoDepth); | 759 ASSERT(depth2 == kInvalidProtoDepth); |
| 754 } | 760 } |
| 755 | 761 |
| 756 // Invoke function. | 762 // Invoke function. |
| 757 if (can_do_fast_api_call) { | 763 if (can_do_fast_api_call) { |
| 758 MaybeObject* result = GenerateFastApiDirectCall(masm, | 764 MaybeObject* result = GenerateFastApiDirectCall(masm, |
| 759 optimization, | 765 optimization, |
| 760 arguments_.immediate()); | 766 arguments_.immediate()); |
| 761 if (result->IsFailure()) return result; | 767 if (result->IsFailure()) return result; |
| 762 } else { | 768 } else { |
| 769 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
| 770 ? CALL_AS_FUNCTION |
| 771 : CALL_AS_METHOD; |
| 763 __ InvokeFunction(optimization.constant_function(), arguments_, | 772 __ InvokeFunction(optimization.constant_function(), arguments_, |
| 764 JUMP_FUNCTION); | 773 JUMP_FUNCTION, call_kind); |
| 765 } | 774 } |
| 766 | 775 |
| 767 // Deferred code for fast API call case---clean preallocated space. | 776 // Deferred code for fast API call case---clean preallocated space. |
| 768 if (can_do_fast_api_call) { | 777 if (can_do_fast_api_call) { |
| 769 __ bind(&miss_cleanup); | 778 __ bind(&miss_cleanup); |
| 770 FreeSpaceForFastApiCall(masm); | 779 FreeSpaceForFastApiCall(masm); |
| 771 __ Branch(miss_label); | 780 __ Branch(miss_label); |
| 772 } | 781 } |
| 773 | 782 |
| 774 // Invoke a regular function. | 783 // Invoke a regular function. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 __ LeaveInternalFrame(); | 846 __ LeaveInternalFrame(); |
| 838 | 847 |
| 839 // If interceptor returns no-result sentinel, call the constant function. | 848 // If interceptor returns no-result sentinel, call the constant function. |
| 840 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); | 849 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); |
| 841 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); | 850 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); |
| 842 } | 851 } |
| 843 | 852 |
| 844 StubCompiler* stub_compiler_; | 853 StubCompiler* stub_compiler_; |
| 845 const ParameterCount& arguments_; | 854 const ParameterCount& arguments_; |
| 846 Register name_; | 855 Register name_; |
| 856 Code::ExtraICState extra_ic_state_; |
| 847 }; | 857 }; |
| 848 | 858 |
| 849 | 859 |
| 850 | 860 |
| 851 // Generate code to check that a global property cell is empty. Create | 861 // Generate code to check that a global property cell is empty. Create |
| 852 // the property cell at compilation time if no cell exists for the | 862 // the property cell at compilation time if no cell exists for the |
| 853 // property. | 863 // property. |
| 854 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 864 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( |
| 855 MacroAssembler* masm, | 865 MacroAssembler* masm, |
| 856 GlobalObject* global, | 866 GlobalObject* global, |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1496 | 1506 |
| 1497 // Get the receiver of the function from the stack into a0. | 1507 // Get the receiver of the function from the stack into a0. |
| 1498 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1508 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
| 1499 // Check that the receiver isn't a smi. | 1509 // Check that the receiver isn't a smi. |
| 1500 __ JumpIfSmi(a0, &miss, t0); | 1510 __ JumpIfSmi(a0, &miss, t0); |
| 1501 | 1511 |
| 1502 // Do the right check and compute the holder register. | 1512 // Do the right check and compute the holder register. |
| 1503 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1513 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); |
| 1504 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); | 1514 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); |
| 1505 | 1515 |
| 1506 GenerateCallFunction(masm(), object, arguments(), &miss); | 1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); |
| 1507 | 1517 |
| 1508 // Handle call cache miss. | 1518 // Handle call cache miss. |
| 1509 __ bind(&miss); | 1519 __ bind(&miss); |
| 1510 MaybeObject* maybe_result = GenerateMissBranch(); | 1520 MaybeObject* maybe_result = GenerateMissBranch(); |
| 1511 if (maybe_result->IsFailure()) return maybe_result; | 1521 if (maybe_result->IsFailure()) return maybe_result; |
| 1512 | 1522 |
| 1513 // Return the generated code. | 1523 // Return the generated code. |
| 1514 return GetCode(FIELD, name); | 1524 return GetCode(FIELD, name); |
| 1515 } | 1525 } |
| 1516 | 1526 |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1994 char_from_code_generator.GenerateFast(masm()); | 2004 char_from_code_generator.GenerateFast(masm()); |
| 1995 __ Drop(argc + 1); | 2005 __ Drop(argc + 1); |
| 1996 __ Ret(); | 2006 __ Ret(); |
| 1997 | 2007 |
| 1998 StubRuntimeCallHelper call_helper; | 2008 StubRuntimeCallHelper call_helper; |
| 1999 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2009 char_from_code_generator.GenerateSlow(masm(), call_helper); |
| 2000 | 2010 |
| 2001 // Tail call the full function. We do not have to patch the receiver | 2011 // Tail call the full function. We do not have to patch the receiver |
| 2002 // because the function makes no use of it. | 2012 // because the function makes no use of it. |
| 2003 __ bind(&slow); | 2013 __ bind(&slow); |
| 2004 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2014 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
| 2005 | 2015 |
| 2006 __ bind(&miss); | 2016 __ bind(&miss); |
| 2007 // a2: function name. | 2017 // a2: function name. |
| 2008 MaybeObject* maybe_result = GenerateMissBranch(); | 2018 MaybeObject* maybe_result = GenerateMissBranch(); |
| 2009 if (maybe_result->IsFailure()) return maybe_result; | 2019 if (maybe_result->IsFailure()) return maybe_result; |
| 2010 | 2020 |
| 2011 // Return the generated code. | 2021 // Return the generated code. |
| 2012 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2022 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
| 2013 } | 2023 } |
| 2014 | 2024 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2079 __ floor_w_d(f0, f0); | 2089 __ floor_w_d(f0, f0); |
| 2080 | 2090 |
| 2081 // Start checking for special cases. | 2091 // Start checking for special cases. |
| 2082 // Get the argument exponent and clear the sign bit. | 2092 // Get the argument exponent and clear the sign bit. |
| 2083 __ lw(t1, FieldMemOperand(v0, HeapNumber::kValueOffset + kPointerSize)); | 2093 __ lw(t1, FieldMemOperand(v0, HeapNumber::kValueOffset + kPointerSize)); |
| 2084 __ And(t2, t1, Operand(~HeapNumber::kSignMask)); | 2094 __ And(t2, t1, Operand(~HeapNumber::kSignMask)); |
| 2085 __ srl(t2, t2, HeapNumber::kMantissaBitsInTopWord); | 2095 __ srl(t2, t2, HeapNumber::kMantissaBitsInTopWord); |
| 2086 | 2096 |
| 2087 // Retrieve FCSR and check for fpu errors. | 2097 // Retrieve FCSR and check for fpu errors. |
| 2088 __ cfc1(t5, FCSR); | 2098 __ cfc1(t5, FCSR); |
| 2089 __ srl(t5, t5, kFCSRFlagShift); | 2099 __ And(t5, t5, Operand(kFCSRExceptionFlagMask)); |
| 2090 // Flag 1 marks an inaccurate but still good result so we ignore it. | |
| 2091 __ And(t5, t5, Operand(kFCSRFlagMask ^ 1)); | |
| 2092 __ Branch(&no_fpu_error, eq, t5, Operand(zero_reg)); | 2100 __ Branch(&no_fpu_error, eq, t5, Operand(zero_reg)); |
| 2093 | 2101 |
| 2094 // Check for NaN, Infinity, and -Infinity. | 2102 // Check for NaN, Infinity, and -Infinity. |
| 2095 // They are invariant through a Math.Floor call, so just | 2103 // They are invariant through a Math.Floor call, so just |
| 2096 // return the original argument. | 2104 // return the original argument. |
| 2097 __ Subu(t3, t2, Operand(HeapNumber::kExponentMask | 2105 __ Subu(t3, t2, Operand(HeapNumber::kExponentMask |
| 2098 >> HeapNumber::kMantissaBitsInTopWord)); | 2106 >> HeapNumber::kMantissaBitsInTopWord)); |
| 2099 __ Branch(&restore_fcsr_and_return, eq, t3, Operand(zero_reg)); | 2107 __ Branch(&restore_fcsr_and_return, eq, t3, Operand(zero_reg)); |
| 2100 // We had an overflow or underflow in the conversion. Check if we | 2108 // We had an overflow or underflow in the conversion. Check if we |
| 2101 // have a big exponent. | 2109 // have a big exponent. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2130 __ Drop(argc + 1); | 2138 __ Drop(argc + 1); |
| 2131 __ Ret(); | 2139 __ Ret(); |
| 2132 | 2140 |
| 2133 __ bind(&wont_fit_smi); | 2141 __ bind(&wont_fit_smi); |
| 2134 // Restore FCSR and fall to slow case. | 2142 // Restore FCSR and fall to slow case. |
| 2135 __ ctc1(a3, FCSR); | 2143 __ ctc1(a3, FCSR); |
| 2136 | 2144 |
| 2137 __ bind(&slow); | 2145 __ bind(&slow); |
| 2138 // Tail call the full function. We do not have to patch the receiver | 2146 // Tail call the full function. We do not have to patch the receiver |
| 2139 // because the function makes no use of it. | 2147 // because the function makes no use of it. |
| 2140 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2148 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
| 2141 | 2149 |
| 2142 __ bind(&miss); | 2150 __ bind(&miss); |
| 2143 // a2: function name. | 2151 // a2: function name. |
| 2144 MaybeObject* obj = GenerateMissBranch(); | 2152 MaybeObject* obj = GenerateMissBranch(); |
| 2145 if (obj->IsFailure()) return obj; | 2153 if (obj->IsFailure()) return obj; |
| 2146 | 2154 |
| 2147 // Return the generated code. | 2155 // Return the generated code. |
| 2148 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2156 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
| 2149 } | 2157 } |
| 2150 | 2158 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); | 2240 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); |
| 2233 __ AllocateHeapNumber(v0, t0, t1, t2, &slow); | 2241 __ AllocateHeapNumber(v0, t0, t1, t2, &slow); |
| 2234 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); | 2242 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); |
| 2235 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); | 2243 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); |
| 2236 __ Drop(argc + 1); | 2244 __ Drop(argc + 1); |
| 2237 __ Ret(); | 2245 __ Ret(); |
| 2238 | 2246 |
| 2239 // Tail call the full function. We do not have to patch the receiver | 2247 // Tail call the full function. We do not have to patch the receiver |
| 2240 // because the function makes no use of it. | 2248 // because the function makes no use of it. |
| 2241 __ bind(&slow); | 2249 __ bind(&slow); |
| 2242 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2250 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
| 2243 | 2251 |
| 2244 __ bind(&miss); | 2252 __ bind(&miss); |
| 2245 // a2: function name. | 2253 // a2: function name. |
| 2246 MaybeObject* maybe_result = GenerateMissBranch(); | 2254 MaybeObject* maybe_result = GenerateMissBranch(); |
| 2247 if (maybe_result->IsFailure()) return maybe_result; | 2255 if (maybe_result->IsFailure()) return maybe_result; |
| 2248 | 2256 |
| 2249 // Return the generated code. | 2257 // Return the generated code. |
| 2250 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2258 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
| 2251 } | 2259 } |
| 2252 | 2260 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2418 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, | 2426 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, |
| 2419 a1, t0, name, &miss); | 2427 a1, t0, name, &miss); |
| 2420 } | 2428 } |
| 2421 break; | 2429 break; |
| 2422 } | 2430 } |
| 2423 | 2431 |
| 2424 default: | 2432 default: |
| 2425 UNREACHABLE(); | 2433 UNREACHABLE(); |
| 2426 } | 2434 } |
| 2427 | 2435 |
| 2428 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2436 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
| 2437 ? CALL_AS_FUNCTION |
| 2438 : CALL_AS_METHOD; |
| 2439 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
| 2429 | 2440 |
| 2430 // Handle call cache miss. | 2441 // Handle call cache miss. |
| 2431 __ bind(&miss); | 2442 __ bind(&miss); |
| 2432 | 2443 |
| 2433 MaybeObject* maybe_result = GenerateMissBranch(); | 2444 MaybeObject* maybe_result = GenerateMissBranch(); |
| 2434 if (maybe_result->IsFailure()) return maybe_result; | 2445 if (maybe_result->IsFailure()) return maybe_result; |
| 2435 | 2446 |
| 2436 // Return the generated code. | 2447 // Return the generated code. |
| 2437 return GetCode(function); | 2448 return GetCode(function); |
| 2438 } | 2449 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2452 | 2463 |
| 2453 // Get the number of arguments. | 2464 // Get the number of arguments. |
| 2454 const int argc = arguments().immediate(); | 2465 const int argc = arguments().immediate(); |
| 2455 | 2466 |
| 2456 LookupResult lookup; | 2467 LookupResult lookup; |
| 2457 LookupPostInterceptor(holder, name, &lookup); | 2468 LookupPostInterceptor(holder, name, &lookup); |
| 2458 | 2469 |
| 2459 // Get the receiver from the stack. | 2470 // Get the receiver from the stack. |
| 2460 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2471 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
| 2461 | 2472 |
| 2462 CallInterceptorCompiler compiler(this, arguments(), a2); | 2473 CallInterceptorCompiler compiler(this, arguments(), a2, extra_ic_state_); |
| 2463 MaybeObject* result = compiler.Compile(masm(), | 2474 MaybeObject* result = compiler.Compile(masm(), |
| 2464 object, | 2475 object, |
| 2465 holder, | 2476 holder, |
| 2466 name, | 2477 name, |
| 2467 &lookup, | 2478 &lookup, |
| 2468 a1, | 2479 a1, |
| 2469 a3, | 2480 a3, |
| 2470 t0, | 2481 t0, |
| 2471 a0, | 2482 a0, |
| 2472 &miss); | 2483 &miss); |
| 2473 if (result->IsFailure()) { | 2484 if (result->IsFailure()) { |
| 2474 return result; | 2485 return result; |
| 2475 } | 2486 } |
| 2476 | 2487 |
| 2477 // Move returned value, the function to call, to a1. | 2488 // Move returned value, the function to call, to a1. |
| 2478 __ mov(a1, v0); | 2489 __ mov(a1, v0); |
| 2479 // Restore receiver. | 2490 // Restore receiver. |
| 2480 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 2491 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
| 2481 | 2492 |
| 2482 GenerateCallFunction(masm(), object, arguments(), &miss); | 2493 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); |
| 2483 | 2494 |
| 2484 // Handle call cache miss. | 2495 // Handle call cache miss. |
| 2485 __ bind(&miss); | 2496 __ bind(&miss); |
| 2486 MaybeObject* maybe_result = GenerateMissBranch(); | 2497 MaybeObject* maybe_result = GenerateMissBranch(); |
| 2487 if (maybe_result->IsFailure()) return maybe_result; | 2498 if (maybe_result->IsFailure()) return maybe_result; |
| 2488 | 2499 |
| 2489 // Return the generated code. | 2500 // Return the generated code. |
| 2490 return GetCode(INTERCEPTOR, name); | 2501 return GetCode(INTERCEPTOR, name); |
| 2491 } | 2502 } |
| 2492 | 2503 |
| 2493 | 2504 |
| 2494 MaybeObject* CallStubCompiler::CompileCallGlobal( | 2505 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
| 2495 JSObject* object, | 2506 GlobalObject* holder, |
| 2496 GlobalObject* holder, | 2507 JSGlobalPropertyCell* cell, |
| 2497 JSGlobalPropertyCell* cell, | 2508 JSFunction* function, |
| 2498 JSFunction* function, | 2509 String* name) { |
| 2499 String* name, | |
| 2500 Code::ExtraICState extra_ic_state) { | |
| 2501 // ----------- S t a t e ------------- | 2510 // ----------- S t a t e ------------- |
| 2502 // -- a2 : name | 2511 // -- a2 : name |
| 2503 // -- ra : return address | 2512 // -- ra : return address |
| 2504 // ----------------------------------- | 2513 // ----------------------------------- |
| 2505 | 2514 |
| 2506 if (HasCustomCallGenerator(function)) { | 2515 if (HasCustomCallGenerator(function)) { |
| 2507 MaybeObject* maybe_result = CompileCustomCall( | 2516 MaybeObject* maybe_result = CompileCustomCall( |
| 2508 object, holder, cell, function, name); | 2517 object, holder, cell, function, name); |
| 2509 Object* result; | 2518 Object* result; |
| 2510 if (!maybe_result->ToObject(&result)) return maybe_result; | 2519 if (!maybe_result->ToObject(&result)) return maybe_result; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2531 | 2540 |
| 2532 // Setup the context (function already in r1). | 2541 // Setup the context (function already in r1). |
| 2533 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 2542 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 2534 | 2543 |
| 2535 // Jump to the cached code (tail call). | 2544 // Jump to the cached code (tail call). |
| 2536 Counters* counters = masm()->isolate()->counters(); | 2545 Counters* counters = masm()->isolate()->counters(); |
| 2537 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2546 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
| 2538 ASSERT(function->is_compiled()); | 2547 ASSERT(function->is_compiled()); |
| 2539 Handle<Code> code(function->code()); | 2548 Handle<Code> code(function->code()); |
| 2540 ParameterCount expected(function->shared()->formal_parameter_count()); | 2549 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2541 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) | 2550 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
| 2542 ? CALL_AS_FUNCTION | 2551 ? CALL_AS_FUNCTION |
| 2543 : CALL_AS_METHOD; | 2552 : CALL_AS_METHOD; |
| 2544 if (V8::UseCrankshaft()) { | 2553 if (V8::UseCrankshaft()) { |
| 2545 UNIMPLEMENTED_MIPS(); | 2554 UNIMPLEMENTED_MIPS(); |
| 2546 } else { | 2555 } else { |
| 2547 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, | 2556 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, |
| 2548 JUMP_FUNCTION, call_kind); | 2557 JUMP_FUNCTION, call_kind); |
| 2549 } | 2558 } |
| 2550 | 2559 |
| 2551 // Handle call cache miss. | 2560 // Handle call cache miss. |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3927 if (array_type == kExternalFloatArray) { | 3936 if (array_type == kExternalFloatArray) { |
| 3928 __ cvt_s_d(f0, f0); | 3937 __ cvt_s_d(f0, f0); |
| 3929 __ sll(t8, t0, 2); | 3938 __ sll(t8, t0, 2); |
| 3930 __ addu(t8, a3, t8); | 3939 __ addu(t8, a3, t8); |
| 3931 __ swc1(f0, MemOperand(t8, 0)); | 3940 __ swc1(f0, MemOperand(t8, 0)); |
| 3932 } else if (array_type == kExternalDoubleArray) { | 3941 } else if (array_type == kExternalDoubleArray) { |
| 3933 __ sll(t8, t0, 3); | 3942 __ sll(t8, t0, 3); |
| 3934 __ addu(t8, a3, t8); | 3943 __ addu(t8, a3, t8); |
| 3935 __ sdc1(f0, MemOperand(t8, 0)); | 3944 __ sdc1(f0, MemOperand(t8, 0)); |
| 3936 } else { | 3945 } else { |
| 3937 Label done; | 3946 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); |
| 3938 | 3947 |
| 3939 // Need to perform float-to-int conversion. | |
| 3940 // Test whether exponent equal to 0x7FF (infinity or NaN). | |
| 3941 | |
| 3942 __ mfc1(t3, f1); // Move exponent word of double to t3 (as raw bits). | |
| 3943 __ li(t1, Operand(0x7FF00000)); | |
| 3944 __ And(t3, t3, Operand(t1)); | |
| 3945 __ Branch(USE_DELAY_SLOT, &done, eq, t3, Operand(t1)); | |
| 3946 __ mov(t3, zero_reg); // In delay slot. | |
| 3947 | |
| 3948 // Not infinity or NaN simply convert to int. | |
| 3949 if (IsElementTypeSigned(array_type)) { | |
| 3950 __ trunc_w_d(f0, f0); | |
| 3951 __ mfc1(t3, f0); | |
| 3952 } else { | |
| 3953 __ Trunc_uw_d(f0, t3); | |
| 3954 } | |
| 3955 | |
| 3956 // t3: HeapNumber converted to integer | |
| 3957 __ bind(&done); | |
| 3958 switch (array_type) { | 3948 switch (array_type) { |
| 3959 case kExternalByteArray: | 3949 case kExternalByteArray: |
| 3960 case kExternalUnsignedByteArray: | 3950 case kExternalUnsignedByteArray: |
| 3961 __ addu(t8, a3, t0); | 3951 __ addu(t8, a3, t0); |
| 3962 __ sb(t3, MemOperand(t8, 0)); | 3952 __ sb(t3, MemOperand(t8, 0)); |
| 3963 break; | 3953 break; |
| 3964 case kExternalShortArray: | 3954 case kExternalShortArray: |
| 3965 case kExternalUnsignedShortArray: | 3955 case kExternalUnsignedShortArray: |
| 3966 __ sll(t8, t0, 1); | 3956 __ sll(t8, t0, 1); |
| 3967 __ addu(t8, a3, t8); | 3957 __ addu(t8, a3, t8); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4276 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4266 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 4277 __ Jump(ic, RelocInfo::CODE_TARGET); | 4267 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 4278 } | 4268 } |
| 4279 | 4269 |
| 4280 | 4270 |
| 4281 #undef __ | 4271 #undef __ |
| 4282 | 4272 |
| 4283 } } // namespace v8::internal | 4273 } } // namespace v8::internal |
| 4284 | 4274 |
| 4285 #endif // V8_TARGET_ARCH_MIPS | 4275 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |