Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | src/mirror-debugger.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
3076 3085
3077 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); 3086 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss);
3078 __ bind(&miss); 3087 __ bind(&miss);
3079 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); 3088 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3);
3080 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3089 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3081 3090
3082 return GetCode(CALLBACKS, name); 3091 return GetCode(CALLBACKS, name);
3083 } 3092 }
3084 3093
3085 3094
3086 MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) { 3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
3087 // ----------- S t a t e ------------- 3096 // ----------- S t a t e -------------
3088 // -- ra : return address 3097 // -- ra : return address
3089 // -- a0 : key 3098 // -- a0 : key
3090 // -- a1 : receiver 3099 // -- a1 : receiver
3091 // ----------------------------------- 3100 // -----------------------------------
3092 MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
3093 Code* stub; 3101 Code* stub;
3102 JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
3103 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
3094 if (!maybe_stub->To(&stub)) return maybe_stub; 3104 if (!maybe_stub->To(&stub)) return maybe_stub;
3095 __ DispatchMap(a1, 3105 __ DispatchMap(a1,
3096 a2, 3106 a2,
3097 Handle<Map>(receiver_map), 3107 Handle<Map>(receiver_map),
3098 Handle<Code>(stub), 3108 Handle<Code>(stub),
3099 DO_SMI_CHECK); 3109 DO_SMI_CHECK);
3100 3110
3101 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3111 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3102 __ Jump(ic, RelocInfo::CODE_TARGET); 3112 __ Jump(ic, RelocInfo::CODE_TARGET);
3103 3113
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3165 3175
3166 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0); 3176 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0);
3167 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); 3177 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
3168 __ Jump(ic, RelocInfo::CODE_TARGET); 3178 __ Jump(ic, RelocInfo::CODE_TARGET);
3169 3179
3170 // Return the generated code. 3180 // Return the generated code.
3171 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 3181 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
3172 } 3182 }
3173 3183
3174 3184
3175 MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement( 3185 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
3176 Map* receiver_map) {
3177 // ----------- S t a t e ------------- 3186 // ----------- S t a t e -------------
3178 // -- a0 : value 3187 // -- a0 : value
3179 // -- a1 : key 3188 // -- a1 : key
3180 // -- a2 : receiver 3189 // -- a2 : receiver
3181 // -- ra : return address 3190 // -- ra : return address
3182 // -- a3 : scratch 3191 // -- a3 : scratch
3183 // ----------------------------------- 3192 // -----------------------------------
3193 Code* stub;
3194 JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
3184 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 3195 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
3185 MaybeObject* maybe_stub = 3196 MaybeObject* maybe_stub =
3186 KeyedStoreFastElementStub(is_js_array).TryGetCode(); 3197 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
3187 Code* stub;
3188 if (!maybe_stub->To(&stub)) return maybe_stub; 3198 if (!maybe_stub->To(&stub)) return maybe_stub;
3189 __ DispatchMap(a2, 3199 __ DispatchMap(a2,
3190 a3, 3200 a3,
3191 Handle<Map>(receiver_map), 3201 Handle<Map>(receiver_map),
3192 Handle<Code>(stub), 3202 Handle<Code>(stub),
3193 DO_SMI_CHECK); 3203 DO_SMI_CHECK);
3194 3204
3195 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3205 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3196 __ Jump(ic, RelocInfo::CODE_TARGET); 3206 __ Jump(ic, RelocInfo::CODE_TARGET);
3197 3207
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3373 __ bind(&generic_stub_call); 3383 __ bind(&generic_stub_call);
3374 Handle<Code> generic_construct_stub = 3384 Handle<Code> generic_construct_stub =
3375 masm()->isolate()->builtins()->JSConstructStubGeneric(); 3385 masm()->isolate()->builtins()->JSConstructStubGeneric();
3376 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 3386 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
3377 3387
3378 // Return the generated code. 3388 // Return the generated code.
3379 return GetCode(); 3389 return GetCode();
3380 } 3390 }
3381 3391
3382 3392
3383 MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
3384 JSObject*receiver, ExternalArrayType array_type) {
3385 // ----------- S t a t e -------------
3386 // -- ra : return address
3387 // -- a0 : key
3388 // -- a1 : receiver
3389 // -----------------------------------
3390 MaybeObject* maybe_stub =
3391 KeyedLoadExternalArrayStub(array_type).TryGetCode();
3392 Code* stub;
3393 if (!maybe_stub->To(&stub)) return maybe_stub;
3394 __ DispatchMap(a1,
3395 a2,
3396 Handle<Map>(receiver->map()),
3397 Handle<Code>(stub),
3398 DO_SMI_CHECK);
3399
3400 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3401 __ Jump(ic, RelocInfo::CODE_TARGET);
3402
3403 // Return the generated code.
3404 return GetCode();
3405 }
3406
3407
3408 MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
3409 JSObject* receiver, ExternalArrayType array_type) {
3410 // ----------- S t a t e -------------
3411 // -- a0 : value
3412 // -- a1 : name
3413 // -- a2 : receiver
3414 // -- ra : return address
3415 // -----------------------------------
3416 MaybeObject* maybe_stub =
3417 KeyedStoreExternalArrayStub(array_type).TryGetCode();
3418 Code* stub;
3419 if (!maybe_stub->To(&stub)) return maybe_stub;
3420 __ DispatchMap(a2,
3421 a3,
3422 Handle<Map>(receiver->map()),
3423 Handle<Code>(stub),
3424 DO_SMI_CHECK);
3425
3426 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
3427 __ Jump(ic, RelocInfo::CODE_TARGET);
3428
3429 return GetCode();
3430 }
3431
3432
3433 #undef __ 3393 #undef __
3434 #define __ ACCESS_MASM(masm) 3394 #define __ ACCESS_MASM(masm)
3435 3395
3436 3396
3437 static bool IsElementTypeSigned(ExternalArrayType array_type) { 3397 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
3438 switch (array_type) { 3398 MacroAssembler* masm) {
3439 case kExternalByteArray: 3399 // ---------- S t a t e --------------
3440 case kExternalShortArray: 3400 // -- ra : return address
3441 case kExternalIntArray: 3401 // -- a0 : key
3402 // -- a1 : receiver
3403 // -----------------------------------
3404 Label slow, miss_force_generic;
3405
3406 Register key = a0;
3407 Register receiver = a1;
3408
3409 __ JumpIfNotSmi(key, &miss_force_generic);
3410 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
3411 __ sra(a2, a0, kSmiTagSize);
3412 __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
3413 __ Ret();
3414
3415 // Slow case, key and receiver still in a0 and a1.
3416 __ bind(&slow);
3417 __ IncrementCounter(
3418 masm->isolate()->counters()->keyed_load_external_array_slow(),
3419 1, a2, a3);
3420 // Entry registers are intact.
3421 // ---------- S t a t e --------------
3422 // -- ra : return address
3423 // -- a0 : key
3424 // -- a1 : receiver
3425 // -----------------------------------
3426 Handle<Code> slow_ic =
3427 masm->isolate()->builtins()->KeyedLoadIC_Slow();
3428 __ Jump(slow_ic, RelocInfo::CODE_TARGET);
3429
3430 // Miss case, call the runtime.
3431 __ bind(&miss_force_generic);
3432
3433 // ---------- S t a t e --------------
3434 // -- ra : return address
3435 // -- a0 : key
3436 // -- a1 : receiver
3437 // -----------------------------------
3438
3439 Handle<Code> miss_ic =
3440 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3441 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3442 }
3443
3444
3445 static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) {
3446 switch (elements_kind) {
3447 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3448 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3449 case JSObject::EXTERNAL_INT_ELEMENTS:
3442 return true; 3450 return true;
3443 3451
3444 case kExternalUnsignedByteArray: 3452 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3445 case kExternalUnsignedShortArray: 3453 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3446 case kExternalUnsignedIntArray: 3454 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3455 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3447 return false; 3456 return false;
3448 3457
3449 default: 3458 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3459 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3460 case JSObject::FAST_ELEMENTS:
3461 case JSObject::FAST_DOUBLE_ELEMENTS:
3462 case JSObject::DICTIONARY_ELEMENTS:
3463 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
3450 UNREACHABLE(); 3464 UNREACHABLE();
3451 return false; 3465 return false;
3452 } 3466 }
3467 return false;
3453 } 3468 }
3454 3469
3455 3470
3456 void KeyedLoadStubCompiler::GenerateLoadExternalArray( 3471 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
3457 MacroAssembler* masm, 3472 MacroAssembler* masm,
3458 ExternalArrayType array_type) { 3473 JSObject::ElementsKind elements_kind) {
3459 // ---------- S t a t e -------------- 3474 // ---------- S t a t e --------------
3460 // -- ra : return address 3475 // -- ra : return address
3461 // -- a0 : key 3476 // -- a0 : key
3462 // -- a1 : receiver 3477 // -- a1 : receiver
3463 // ----------------------------------- 3478 // -----------------------------------
3464 Label miss_force_generic, slow, failed_allocation; 3479 Label miss_force_generic, slow, failed_allocation;
3465 3480
3466 Register key = a0; 3481 Register key = a0;
3467 Register receiver = a1; 3482 Register receiver = a1;
3468 3483
(...skipping 13 matching lines...) Expand all
3482 __ Branch(&miss_force_generic, Uless, t1, Operand(t2)); 3497 __ Branch(&miss_force_generic, Uless, t1, Operand(t2));
3483 3498
3484 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); 3499 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
3485 // a3: base pointer of external storage 3500 // a3: base pointer of external storage
3486 3501
3487 // We are not untagging smi key and instead work with it 3502 // We are not untagging smi key and instead work with it
3488 // as if it was premultiplied by 2. 3503 // as if it was premultiplied by 2.
3489 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1)); 3504 ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
3490 3505
3491 Register value = a2; 3506 Register value = a2;
3492 switch (array_type) { 3507 switch (elements_kind) {
3493 case kExternalByteArray: 3508 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3494 __ srl(t2, key, 1); 3509 __ srl(t2, key, 1);
3495 __ addu(t3, a3, t2); 3510 __ addu(t3, a3, t2);
3496 __ lb(value, MemOperand(t3, 0)); 3511 __ lb(value, MemOperand(t3, 0));
3497 break; 3512 break;
3498 case kExternalPixelArray: 3513 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3499 case kExternalUnsignedByteArray: 3514 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3500 __ srl(t2, key, 1); 3515 __ srl(t2, key, 1);
3501 __ addu(t3, a3, t2); 3516 __ addu(t3, a3, t2);
3502 __ lbu(value, MemOperand(t3, 0)); 3517 __ lbu(value, MemOperand(t3, 0));
3503 break; 3518 break;
3504 case kExternalShortArray: 3519 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3505 __ addu(t3, a3, key); 3520 __ addu(t3, a3, key);
3506 __ lh(value, MemOperand(t3, 0)); 3521 __ lh(value, MemOperand(t3, 0));
3507 break; 3522 break;
3508 case kExternalUnsignedShortArray: 3523 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3509 __ addu(t3, a3, key); 3524 __ addu(t3, a3, key);
3510 __ lhu(value, MemOperand(t3, 0)); 3525 __ lhu(value, MemOperand(t3, 0));
3511 break; 3526 break;
3512 case kExternalIntArray: 3527 case JSObject::EXTERNAL_INT_ELEMENTS:
3513 case kExternalUnsignedIntArray: 3528 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3514 __ sll(t2, key, 1); 3529 __ sll(t2, key, 1);
3515 __ addu(t3, a3, t2); 3530 __ addu(t3, a3, t2);
3516 __ lw(value, MemOperand(t3, 0)); 3531 __ lw(value, MemOperand(t3, 0));
3517 break; 3532 break;
3518 case kExternalFloatArray: 3533 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3519 __ sll(t3, t2, 2); 3534 __ sll(t3, t2, 2);
3520 __ addu(t3, a3, t3); 3535 __ addu(t3, a3, t3);
3521 if (CpuFeatures::IsSupported(FPU)) { 3536 if (CpuFeatures::IsSupported(FPU)) {
3522 CpuFeatures::Scope scope(FPU); 3537 CpuFeatures::Scope scope(FPU);
3523 __ lwc1(f0, MemOperand(t3, 0)); 3538 __ lwc1(f0, MemOperand(t3, 0));
3524 } else { 3539 } else {
3525 __ lw(value, MemOperand(t3, 0)); 3540 __ lw(value, MemOperand(t3, 0));
3526 } 3541 }
3527 break; 3542 break;
3528 case kExternalDoubleArray: 3543 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3529 __ sll(t2, key, 2); 3544 __ sll(t2, key, 2);
3530 __ addu(t3, a3, t2); 3545 __ addu(t3, a3, t2);
3531 if (CpuFeatures::IsSupported(FPU)) { 3546 if (CpuFeatures::IsSupported(FPU)) {
3532 CpuFeatures::Scope scope(FPU); 3547 CpuFeatures::Scope scope(FPU);
3533 __ ldc1(f0, MemOperand(t3, 0)); 3548 __ ldc1(f0, MemOperand(t3, 0));
3534 } else { 3549 } else {
3535 // t3: pointer to the beginning of the double we want to load. 3550 // t3: pointer to the beginning of the double we want to load.
3536 __ lw(a2, MemOperand(t3, 0)); 3551 __ lw(a2, MemOperand(t3, 0));
3537 __ lw(a3, MemOperand(t3, Register::kSizeInBytes)); 3552 __ lw(a3, MemOperand(t3, Register::kSizeInBytes));
3538 } 3553 }
3539 break; 3554 break;
3540 default: 3555 case JSObject::FAST_ELEMENTS:
3556 case JSObject::FAST_DOUBLE_ELEMENTS:
3557 case JSObject::DICTIONARY_ELEMENTS:
3558 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
3541 UNREACHABLE(); 3559 UNREACHABLE();
3542 break; 3560 break;
3543 } 3561 }
3544 3562
3545 // For integer array types: 3563 // For integer array types:
3546 // a2: value 3564 // a2: value
3547 // For float array type: 3565 // For float array type:
3548 // f0: value (if FPU is supported) 3566 // f0: value (if FPU is supported)
3549 // a2: value (if FPU is not supported) 3567 // a2: value (if FPU is not supported)
3550 // For double array type: 3568 // For double array type:
3551 // f0: value (if FPU is supported) 3569 // f0: value (if FPU is supported)
3552 // a2/a3: value (if FPU is not supported) 3570 // a2/a3: value (if FPU is not supported)
3553 3571
3554 if (array_type == kExternalIntArray) { 3572 if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
3555 // For the Int and UnsignedInt array types, we need to see whether 3573 // For the Int and UnsignedInt array types, we need to see whether
3556 // the value can be represented in a Smi. If not, we need to convert 3574 // the value can be represented in a Smi. If not, we need to convert
3557 // it to a HeapNumber. 3575 // it to a HeapNumber.
3558 Label box_int; 3576 Label box_int;
3559 __ Subu(t3, value, Operand(0xC0000000)); // Non-smi value gives neg result. 3577 __ Subu(t3, value, Operand(0xC0000000)); // Non-smi value gives neg result.
3560 __ Branch(&box_int, lt, t3, Operand(zero_reg)); 3578 __ Branch(&box_int, lt, t3, Operand(zero_reg));
3561 // Tag integer as smi and return it. 3579 // Tag integer as smi and return it.
3562 __ sll(v0, value, kSmiTagSize); 3580 __ sll(v0, value, kSmiTagSize);
3563 __ Ret(); 3581 __ Ret();
3564 3582
(...skipping 21 matching lines...) Expand all
3586 dest, 3604 dest,
3587 f0, 3605 f0,
3588 dst1, 3606 dst1,
3589 dst2, 3607 dst2,
3590 t1, 3608 t1,
3591 f2); 3609 f2);
3592 __ sw(dst1, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 3610 __ sw(dst1, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
3593 __ sw(dst2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 3611 __ sw(dst2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
3594 __ Ret(); 3612 __ Ret();
3595 } 3613 }
3596 } else if (array_type == kExternalUnsignedIntArray) { 3614 } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
3597 // The test is different for unsigned int values. Since we need 3615 // The test is different for unsigned int values. Since we need
3598 // the value to be in the range of a positive smi, we can't 3616 // the value to be in the range of a positive smi, we can't
3599 // handle either of the top two bits being set in the value. 3617 // handle either of the top two bits being set in the value.
3600 if (CpuFeatures::IsSupported(FPU)) { 3618 if (CpuFeatures::IsSupported(FPU)) {
3601 CpuFeatures::Scope scope(FPU); 3619 CpuFeatures::Scope scope(FPU);
3602 Label pl_box_int; 3620 Label pl_box_int;
3603 __ And(t2, value, Operand(0xC0000000)); 3621 __ And(t2, value, Operand(0xC0000000));
3604 __ Branch(&pl_box_int, ne, t2, Operand(zero_reg)); 3622 __ Branch(&pl_box_int, ne, t2, Operand(zero_reg));
3605 3623
3606 // It can fit in an Smi. 3624 // It can fit in an Smi.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3657 // space. 3675 // space.
3658 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); 3676 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
3659 __ AllocateHeapNumber(t2, t3, t5, t6, &slow); 3677 __ AllocateHeapNumber(t2, t3, t5, t6, &slow);
3660 3678
3661 __ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset)); 3679 __ sw(hiword, FieldMemOperand(t2, HeapNumber::kExponentOffset));
3662 __ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset)); 3680 __ sw(loword, FieldMemOperand(t2, HeapNumber::kMantissaOffset));
3663 3681
3664 __ mov(v0, t2); 3682 __ mov(v0, t2);
3665 __ Ret(); 3683 __ Ret();
3666 } 3684 }
3667 } else if (array_type == kExternalFloatArray) { 3685 } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3668 // For the floating-point array type, we need to always allocate a 3686 // For the floating-point array type, we need to always allocate a
3669 // HeapNumber. 3687 // HeapNumber.
3670 if (CpuFeatures::IsSupported(FPU)) { 3688 if (CpuFeatures::IsSupported(FPU)) {
3671 CpuFeatures::Scope scope(FPU); 3689 CpuFeatures::Scope scope(FPU);
3672 // Allocate a HeapNumber for the result. Don't use a0 and a1 as 3690 // Allocate a HeapNumber for the result. Don't use a0 and a1 as
3673 // AllocateHeapNumber clobbers all registers - also when jumping due to 3691 // AllocateHeapNumber clobbers all registers - also when jumping due to
3674 // exhausted young space. 3692 // exhausted young space.
3675 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); 3693 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
3676 __ AllocateHeapNumber(v0, t3, t5, t6, &slow); 3694 __ AllocateHeapNumber(v0, t3, t5, t6, &slow);
3677 // The float (single) value is already in fpu reg f0 (if we use float). 3695 // The float (single) value is already in fpu reg f0 (if we use float).
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3724 3742
3725 __ srl(t0, t4, kMantissaShiftForHiWord); 3743 __ srl(t0, t4, kMantissaShiftForHiWord);
3726 __ or_(a2, a2, t0); 3744 __ or_(a2, a2, t0);
3727 __ sll(a0, t4, kMantissaShiftForLoWord); 3745 __ sll(a0, t4, kMantissaShiftForLoWord);
3728 3746
3729 __ sw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 3747 __ sw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
3730 __ sw(a0, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 3748 __ sw(a0, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
3731 __ Ret(); 3749 __ Ret();
3732 } 3750 }
3733 3751
3734 } else if (array_type == kExternalDoubleArray) { 3752 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3735 if (CpuFeatures::IsSupported(FPU)) { 3753 if (CpuFeatures::IsSupported(FPU)) {
3736 CpuFeatures::Scope scope(FPU); 3754 CpuFeatures::Scope scope(FPU);
3737 // Allocate a HeapNumber for the result. Don't use a0 and a1 as 3755 // Allocate a HeapNumber for the result. Don't use a0 and a1 as
3738 // AllocateHeapNumber clobbers all registers - also when jumping due to 3756 // AllocateHeapNumber clobbers all registers - also when jumping due to
3739 // exhausted young space. 3757 // exhausted young space.
3740 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); 3758 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex);
3741 __ AllocateHeapNumber(v0, t3, t5, t6, &slow); 3759 __ AllocateHeapNumber(v0, t3, t5, t6, &slow);
3742 // The double value is already in f0 3760 // The double value is already in f0
3743 __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); 3761 __ sdc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset));
3744 __ Ret(); 3762 __ Ret();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3778 3796
3779 __ bind(&miss_force_generic); 3797 __ bind(&miss_force_generic);
3780 Code* stub = masm->isolate()->builtins()->builtin( 3798 Code* stub = masm->isolate()->builtins()->builtin(
3781 Builtins::kKeyedLoadIC_MissForceGeneric); 3799 Builtins::kKeyedLoadIC_MissForceGeneric);
3782 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET); 3800 __ Jump(Handle<Code>(stub), RelocInfo::CODE_TARGET);
3783 } 3801 }
3784 3802
3785 3803
3786 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3804 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3787 MacroAssembler* masm, 3805 MacroAssembler* masm,
3788 ExternalArrayType array_type) { 3806 JSObject::ElementsKind elements_kind) {
3789 // ---------- S t a t e -------------- 3807 // ---------- S t a t e --------------
3790 // -- a0 : value 3808 // -- a0 : value
3791 // -- a1 : key 3809 // -- a1 : key
3792 // -- a2 : receiver 3810 // -- a2 : receiver
3793 // -- ra : return address 3811 // -- ra : return address
3794 // ----------------------------------- 3812 // -----------------------------------
3795 3813
3796 Label slow, check_heap_number, miss_force_generic; 3814 Label slow, check_heap_number, miss_force_generic;
3797 3815
3798 // Register usage. 3816 // Register usage.
(...skipping 14 matching lines...) Expand all
3813 __ SmiUntag(t0, key); 3831 __ SmiUntag(t0, key);
3814 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); 3832 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset));
3815 // Unsigned comparison catches both negative and too-large values. 3833 // Unsigned comparison catches both negative and too-large values.
3816 __ Branch(&miss_force_generic, Ugreater_equal, t0, Operand(t1)); 3834 __ Branch(&miss_force_generic, Ugreater_equal, t0, Operand(t1));
3817 3835
3818 // Handle both smis and HeapNumbers in the fast path. Go to the 3836 // Handle both smis and HeapNumbers in the fast path. Go to the
3819 // runtime for all other kinds of values. 3837 // runtime for all other kinds of values.
3820 // a3: external array. 3838 // a3: external array.
3821 // t0: key (integer). 3839 // t0: key (integer).
3822 3840
3823 if (array_type == kExternalPixelArray) { 3841 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
3824 // Double to pixel conversion is only implemented in the runtime for now. 3842 // Double to pixel conversion is only implemented in the runtime for now.
3825 __ JumpIfNotSmi(value, &slow); 3843 __ JumpIfNotSmi(value, &slow);
3826 } else { 3844 } else {
3827 __ JumpIfNotSmi(value, &check_heap_number); 3845 __ JumpIfNotSmi(value, &check_heap_number);
3828 } 3846 }
3829 __ SmiUntag(t1, value); 3847 __ SmiUntag(t1, value);
3830 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); 3848 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
3831 3849
3832 // a3: base pointer of external storage. 3850 // a3: base pointer of external storage.
3833 // t0: key (integer). 3851 // t0: key (integer).
3834 // t1: value (integer). 3852 // t1: value (integer).
3835 3853
3836 switch (array_type) { 3854 switch (elements_kind) {
3837 case kExternalPixelArray: { 3855 case JSObject::EXTERNAL_PIXEL_ELEMENTS: {
3838 // Clamp the value to [0..255]. 3856 // Clamp the value to [0..255].
3839 // v0 is used as a scratch register here. 3857 // v0 is used as a scratch register here.
3840 Label done; 3858 Label done;
3841 __ li(v0, Operand(255)); 3859 __ li(v0, Operand(255));
3842 // Normal branch: nop in delay slot. 3860 // Normal branch: nop in delay slot.
3843 __ Branch(&done, gt, t1, Operand(v0)); 3861 __ Branch(&done, gt, t1, Operand(v0));
3844 // Use delay slot in this branch. 3862 // Use delay slot in this branch.
3845 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg)); 3863 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg));
3846 __ mov(v0, zero_reg); // In delay slot. 3864 __ mov(v0, zero_reg); // In delay slot.
3847 __ mov(v0, t1); // Value is in range 0..255. 3865 __ mov(v0, t1); // Value is in range 0..255.
3848 __ bind(&done); 3866 __ bind(&done);
3849 __ mov(t1, v0); 3867 __ mov(t1, v0);
3850 __ addu(t8, a3, t0); 3868 __ addu(t8, a3, t0);
3851 __ sb(t1, MemOperand(t8, 0)); 3869 __ sb(t1, MemOperand(t8, 0));
3852 } 3870 }
3853 break; 3871 break;
3854 case kExternalByteArray: 3872 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3855 case kExternalUnsignedByteArray: 3873 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3856 __ addu(t8, a3, t0); 3874 __ addu(t8, a3, t0);
3857 __ sb(t1, MemOperand(t8, 0)); 3875 __ sb(t1, MemOperand(t8, 0));
3858 break; 3876 break;
3859 case kExternalShortArray: 3877 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3860 case kExternalUnsignedShortArray: 3878 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3861 __ sll(t8, t0, 1); 3879 __ sll(t8, t0, 1);
3862 __ addu(t8, a3, t8); 3880 __ addu(t8, a3, t8);
3863 __ sh(t1, MemOperand(t8, 0)); 3881 __ sh(t1, MemOperand(t8, 0));
3864 break; 3882 break;
3865 case kExternalIntArray: 3883 case JSObject::EXTERNAL_INT_ELEMENTS:
3866 case kExternalUnsignedIntArray: 3884 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3867 __ sll(t8, t0, 2); 3885 __ sll(t8, t0, 2);
3868 __ addu(t8, a3, t8); 3886 __ addu(t8, a3, t8);
3869 __ sw(t1, MemOperand(t8, 0)); 3887 __ sw(t1, MemOperand(t8, 0));
3870 break; 3888 break;
3871 case kExternalFloatArray: 3889 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3872 // Perform int-to-float conversion and store to memory. 3890 // Perform int-to-float conversion and store to memory.
3873 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); 3891 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4);
3874 break; 3892 break;
3875 case kExternalDoubleArray: 3893 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3876 __ sll(t8, t0, 3); 3894 __ sll(t8, t0, 3);
3877 __ addu(a3, a3, t8); 3895 __ addu(a3, a3, t8);
3878 // a3: effective address of the double element 3896 // a3: effective address of the double element
3879 FloatingPointHelper::Destination destination; 3897 FloatingPointHelper::Destination destination;
3880 if (CpuFeatures::IsSupported(FPU)) { 3898 if (CpuFeatures::IsSupported(FPU)) {
3881 destination = FloatingPointHelper::kFPURegisters; 3899 destination = FloatingPointHelper::kFPURegisters;
3882 } else { 3900 } else {
3883 destination = FloatingPointHelper::kCoreRegisters; 3901 destination = FloatingPointHelper::kCoreRegisters;
3884 } 3902 }
3885 FloatingPointHelper::ConvertIntToDouble( 3903 FloatingPointHelper::ConvertIntToDouble(
3886 masm, t1, destination, 3904 masm, t1, destination,
3887 f0, t2, t3, // These are: double_dst, dst1, dst2. 3905 f0, t2, t3, // These are: double_dst, dst1, dst2.
3888 t0, f2); // These are: scratch2, single_scratch. 3906 t0, f2); // These are: scratch2, single_scratch.
3889 if (destination == FloatingPointHelper::kFPURegisters) { 3907 if (destination == FloatingPointHelper::kFPURegisters) {
3890 CpuFeatures::Scope scope(FPU); 3908 CpuFeatures::Scope scope(FPU);
3891 __ sdc1(f0, MemOperand(a3, 0)); 3909 __ sdc1(f0, MemOperand(a3, 0));
3892 } else { 3910 } else {
3893 __ sw(t2, MemOperand(a3, 0)); 3911 __ sw(t2, MemOperand(a3, 0));
3894 __ sw(t3, MemOperand(a3, Register::kSizeInBytes)); 3912 __ sw(t3, MemOperand(a3, Register::kSizeInBytes));
3895 } 3913 }
3896 break; 3914 break;
3897 default: 3915 case JSObject::FAST_ELEMENTS:
3916 case JSObject::FAST_DOUBLE_ELEMENTS:
3917 case JSObject::DICTIONARY_ELEMENTS:
3918 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
3898 UNREACHABLE(); 3919 UNREACHABLE();
3899 break; 3920 break;
3900 } 3921 }
3901 3922
3902 // Entry registers are intact, a0 holds the value which is the return value. 3923 // Entry registers are intact, a0 holds the value which is the return value.
3903 __ mov(v0, value); 3924 __ mov(v0, value);
3904 __ Ret(); 3925 __ Ret();
3905 3926
3906 if (array_type != kExternalPixelArray) { 3927 if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
3907 // a3: external array. 3928 // a3: external array.
3908 // t0: index (integer). 3929 // t0: index (integer).
3909 __ bind(&check_heap_number); 3930 __ bind(&check_heap_number);
3910 __ GetObjectType(value, t1, t2); 3931 __ GetObjectType(value, t1, t2);
3911 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); 3932 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE));
3912 3933
3913 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); 3934 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
3914 3935
3915 // a3: base pointer of external storage. 3936 // a3: base pointer of external storage.
3916 // t0: key (integer). 3937 // t0: key (integer).
3917 3938
3918 // The WebGL specification leaves the behavior of storing NaN and 3939 // The WebGL specification leaves the behavior of storing NaN and
3919 // +/-Infinity into integer arrays basically undefined. For more 3940 // +/-Infinity into integer arrays basically undefined. For more
3920 // reproducible behavior, convert these to zero. 3941 // reproducible behavior, convert these to zero.
3921 3942
3922 if (CpuFeatures::IsSupported(FPU)) { 3943 if (CpuFeatures::IsSupported(FPU)) {
3923 CpuFeatures::Scope scope(FPU); 3944 CpuFeatures::Scope scope(FPU);
3924 3945
3925 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); 3946 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset));
3926 3947
3927 if (array_type == kExternalFloatArray) { 3948 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3928 __ cvt_s_d(f0, f0); 3949 __ cvt_s_d(f0, f0);
3929 __ sll(t8, t0, 2); 3950 __ sll(t8, t0, 2);
3930 __ addu(t8, a3, t8); 3951 __ addu(t8, a3, t8);
3931 __ swc1(f0, MemOperand(t8, 0)); 3952 __ swc1(f0, MemOperand(t8, 0));
3932 } else if (array_type == kExternalDoubleArray) { 3953 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3933 __ sll(t8, t0, 3); 3954 __ sll(t8, t0, 3);
3934 __ addu(t8, a3, t8); 3955 __ addu(t8, a3, t8);
3935 __ sdc1(f0, MemOperand(t8, 0)); 3956 __ sdc1(f0, MemOperand(t8, 0));
3936 } else { 3957 } else {
3937 Label done; 3958 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5);
3938 3959
3939 // Need to perform float-to-int conversion. 3960 switch (elements_kind) {
3940 // Test whether exponent equal to 0x7FF (infinity or NaN). 3961 case JSObject::EXTERNAL_BYTE_ELEMENTS:
3941 3962 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
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) {
3959 case kExternalByteArray:
3960 case kExternalUnsignedByteArray:
3961 __ addu(t8, a3, t0); 3963 __ addu(t8, a3, t0);
3962 __ sb(t3, MemOperand(t8, 0)); 3964 __ sb(t3, MemOperand(t8, 0));
3963 break; 3965 break;
3964 case kExternalShortArray: 3966 case JSObject::EXTERNAL_SHORT_ELEMENTS:
3965 case kExternalUnsignedShortArray: 3967 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3966 __ sll(t8, t0, 1); 3968 __ sll(t8, t0, 1);
3967 __ addu(t8, a3, t8); 3969 __ addu(t8, a3, t8);
3968 __ sh(t3, MemOperand(t8, 0)); 3970 __ sh(t3, MemOperand(t8, 0));
3969 break; 3971 break;
3970 case kExternalIntArray: 3972 case JSObject::EXTERNAL_INT_ELEMENTS:
3971 case kExternalUnsignedIntArray: 3973 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
3972 __ sll(t8, t0, 2); 3974 __ sll(t8, t0, 2);
3973 __ addu(t8, a3, t8); 3975 __ addu(t8, a3, t8);
3974 __ sw(t3, MemOperand(t8, 0)); 3976 __ sw(t3, MemOperand(t8, 0));
3975 break; 3977 break;
3976 default: 3978 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3979 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
3980 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
3981 case JSObject::FAST_ELEMENTS:
3982 case JSObject::FAST_DOUBLE_ELEMENTS:
3983 case JSObject::DICTIONARY_ELEMENTS:
3984 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
3977 UNREACHABLE(); 3985 UNREACHABLE();
3978 break; 3986 break;
3979 } 3987 }
3980 } 3988 }
3981 3989
3982 // Entry registers are intact, a0 holds the value 3990 // Entry registers are intact, a0 holds the value
3983 // which is the return value. 3991 // which is the return value.
3984 __ mov(v0, value); 3992 __ mov(v0, value);
3985 __ Ret(); 3993 __ Ret();
3986 } else { 3994 } else {
3987 // FPU is not available, do manual conversions. 3995 // FPU is not available, do manual conversions.
3988 3996
3989 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset)); 3997 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset));
3990 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset)); 3998 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset));
3991 3999
3992 if (array_type == kExternalFloatArray) { 4000 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3993 Label done, nan_or_infinity_or_zero; 4001 Label done, nan_or_infinity_or_zero;
3994 static const int kMantissaInHiWordShift = 4002 static const int kMantissaInHiWordShift =
3995 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; 4003 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3996 4004
3997 static const int kMantissaInLoWordShift = 4005 static const int kMantissaInLoWordShift =
3998 kBitsPerInt - kMantissaInHiWordShift; 4006 kBitsPerInt - kMantissaInHiWordShift;
3999 4007
4000 // Test for all special exponent values: zeros, subnormal numbers, NaNs 4008 // Test for all special exponent values: zeros, subnormal numbers, NaNs
4001 // and infinities. All these should be converted to 0. 4009 // and infinities. All these should be converted to 0.
4002 __ li(t5, HeapNumber::kExponentMask); 4010 __ li(t5, HeapNumber::kExponentMask);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4047 4055
4048 __ bind(&nan_or_infinity_or_zero); 4056 __ bind(&nan_or_infinity_or_zero);
4049 __ And(t7, t3, Operand(HeapNumber::kSignMask)); 4057 __ And(t7, t3, Operand(HeapNumber::kSignMask));
4050 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); 4058 __ And(t3, t3, Operand(HeapNumber::kMantissaMask));
4051 __ or_(t6, t6, t7); 4059 __ or_(t6, t6, t7);
4052 __ sll(t3, t3, kMantissaInHiWordShift); 4060 __ sll(t3, t3, kMantissaInHiWordShift);
4053 __ or_(t6, t6, t3); 4061 __ or_(t6, t6, t3);
4054 __ srl(t4, t4, kMantissaInLoWordShift); 4062 __ srl(t4, t4, kMantissaInLoWordShift);
4055 __ or_(t3, t6, t4); 4063 __ or_(t3, t6, t4);
4056 __ Branch(&done); 4064 __ Branch(&done);
4057 } else if (array_type == kExternalDoubleArray) { 4065 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
4058 __ sll(t8, t0, 3); 4066 __ sll(t8, t0, 3);
4059 __ addu(t8, a3, t8); 4067 __ addu(t8, a3, t8);
4060 // t8: effective address of destination element. 4068 // t8: effective address of destination element.
4061 __ sw(t4, MemOperand(t8, 0)); 4069 __ sw(t4, MemOperand(t8, 0));
4062 __ sw(t3, MemOperand(t8, Register::kSizeInBytes)); 4070 __ sw(t3, MemOperand(t8, Register::kSizeInBytes));
4063 __ Ret(); 4071 __ Ret();
4064 } else { 4072 } else {
4065 bool is_signed_type = IsElementTypeSigned(array_type); 4073 bool is_signed_type = IsElementTypeSigned(elements_kind);
4066 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; 4074 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
4067 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; 4075 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
4068 4076
4069 Label done, sign; 4077 Label done, sign;
4070 4078
4071 // Test for all special exponent values: zeros, subnormal numbers, NaNs 4079 // Test for all special exponent values: zeros, subnormal numbers, NaNs
4072 // and infinities. All these should be converted to 0. 4080 // and infinities. All these should be converted to 0.
4073 __ li(t5, HeapNumber::kExponentMask); 4081 __ li(t5, HeapNumber::kExponentMask);
4074 __ and_(t6, t3, t5); 4082 __ and_(t6, t3, t5);
4075 __ movz(t3, zero_reg, t6); // Only if t6 is equal to zero. 4083 __ movz(t3, zero_reg, t6); // Only if t6 is equal to zero.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4112 __ or_(t3, t3, t4); 4120 __ or_(t3, t3, t4);
4113 4121
4114 __ bind(&sign); 4122 __ bind(&sign);
4115 __ subu(t2, t3, zero_reg); 4123 __ subu(t2, t3, zero_reg);
4116 __ movz(t3, t2, t5); // Only if t5 is zero. 4124 __ movz(t3, t2, t5); // Only if t5 is zero.
4117 4125
4118 __ bind(&done); 4126 __ bind(&done);
4119 4127
4120 // Result is in t3. 4128 // Result is in t3.
4121 // This switch block should be exactly the same as above (FPU mode). 4129 // This switch block should be exactly the same as above (FPU mode).
4122 switch (array_type) { 4130 switch (elements_kind) {
4123 case kExternalByteArray: 4131 case JSObject::EXTERNAL_BYTE_ELEMENTS:
4124 case kExternalUnsignedByteArray: 4132 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4125 __ addu(t8, a3, t0); 4133 __ addu(t8, a3, t0);
4126 __ sb(t3, MemOperand(t8, 0)); 4134 __ sb(t3, MemOperand(t8, 0));
4127 break; 4135 break;
4128 case kExternalShortArray: 4136 case JSObject::EXTERNAL_SHORT_ELEMENTS:
4129 case kExternalUnsignedShortArray: 4137 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4130 __ sll(t8, t0, 1); 4138 __ sll(t8, t0, 1);
4131 __ addu(t8, a3, t8); 4139 __ addu(t8, a3, t8);
4132 __ sh(t3, MemOperand(t8, 0)); 4140 __ sh(t3, MemOperand(t8, 0));
4133 break; 4141 break;
4134 case kExternalIntArray: 4142 case JSObject::EXTERNAL_INT_ELEMENTS:
4135 case kExternalUnsignedIntArray: 4143 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
4136 __ sll(t8, t0, 2); 4144 __ sll(t8, t0, 2);
4137 __ addu(t8, a3, t8); 4145 __ addu(t8, a3, t8);
4138 __ sw(t3, MemOperand(t8, 0)); 4146 __ sw(t3, MemOperand(t8, 0));
4139 break; 4147 break;
4140 default: 4148 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
4149 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
4150 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
4151 case JSObject::FAST_ELEMENTS:
4152 case JSObject::FAST_DOUBLE_ELEMENTS:
4153 case JSObject::DICTIONARY_ELEMENTS:
4154 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
4141 UNREACHABLE(); 4155 UNREACHABLE();
4142 break; 4156 break;
4143 } 4157 }
4144 } 4158 }
4145 } 4159 }
4146 } 4160 }
4147 4161
4148 // Slow case, key and receiver still in a0 and a1. 4162 // Slow case, key and receiver still in a0 and a1.
4149 __ bind(&slow); 4163 __ bind(&slow);
4150 __ IncrementCounter( 4164 __ IncrementCounter(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
4232 Register receiver_reg = a2; 4246 Register receiver_reg = a2;
4233 Register scratch = a3; 4247 Register scratch = a3;
4234 Register elements_reg = t0; 4248 Register elements_reg = t0;
4235 Register scratch2 = t1; 4249 Register scratch2 = t1;
4236 Register scratch3 = t2; 4250 Register scratch3 = t2;
4237 4251
4238 // This stub is meant to be tail-jumped to, the receiver must already 4252 // This stub is meant to be tail-jumped to, the receiver must already
4239 // have been verified by the caller to not be a smi. 4253 // have been verified by the caller to not be a smi.
4240 4254
4241 // Check that the key is a smi. 4255 // Check that the key is a smi.
4242 __ JumpIfNotSmi(a0, &miss_force_generic); 4256 __ JumpIfNotSmi(key_reg, &miss_force_generic);
4243 4257
4244 // Get the elements array and make sure it is a fast element array, not 'cow'. 4258 // Get the elements array and make sure it is a fast element array, not 'cow'.
4245 __ lw(elements_reg, 4259 __ lw(elements_reg,
4246 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); 4260 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
4247 __ CheckMap(elements_reg, 4261 __ CheckMap(elements_reg,
4248 scratch, 4262 scratch,
4249 Heap::kFixedArrayMapRootIndex, 4263 Heap::kFixedArrayMapRootIndex,
4250 &miss_force_generic, 4264 &miss_force_generic,
4251 DONT_DO_SMI_CHECK); 4265 DONT_DO_SMI_CHECK);
4252 4266
(...skipping 23 matching lines...) Expand all
4276 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 4290 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
4277 __ Jump(ic, RelocInfo::CODE_TARGET); 4291 __ Jump(ic, RelocInfo::CODE_TARGET);
4278 } 4292 }
4279 4293
4280 4294
4281 #undef __ 4295 #undef __
4282 4296
4283 } } // namespace v8::internal 4297 } } // namespace v8::internal
4284 4298
4285 #endif // V8_TARGET_ARCH_MIPS 4299 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | src/mirror-debugger.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698