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 |