| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 | 5 | 
| 6 | 6 | 
| 7 #include "src/v8.h" | 7 #include "src/v8.h" | 
| 8 | 8 | 
| 9 #if V8_TARGET_ARCH_MIPS | 9 #if V8_TARGET_ARCH_MIPS | 
| 10 | 10 | 
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 165   __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 165   __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
| 166   // Check bit field. | 166   // Check bit field. | 
| 167   __ lbu(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 167   __ lbu(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 
| 168   __ And(at, scratch, | 168   __ And(at, scratch, | 
| 169          Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit))); | 169          Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit))); | 
| 170   __ Branch(slow, ne, at, Operand(zero_reg)); | 170   __ Branch(slow, ne, at, Operand(zero_reg)); | 
| 171   // Check that the object is some kind of JS object EXCEPT JS Value type. | 171   // Check that the object is some kind of JS object EXCEPT JS Value type. | 
| 172   // In the case that the object is a value-wrapper object, | 172   // In the case that the object is a value-wrapper object, | 
| 173   // we enter the runtime system to make sure that indexing into string | 173   // we enter the runtime system to make sure that indexing into string | 
| 174   // objects work as intended. | 174   // objects work as intended. | 
| 175   ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 175   DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 
| 176   __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 176   __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 
| 177   __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE)); | 177   __ Branch(slow, lt, scratch, Operand(JS_OBJECT_TYPE)); | 
| 178 } | 178 } | 
| 179 | 179 | 
| 180 | 180 | 
| 181 // Loads an indexed element from a fast case array. | 181 // Loads an indexed element from a fast case array. | 
| 182 // If not_fast_array is NULL, doesn't perform the elements map check. | 182 // If not_fast_array is NULL, doesn't perform the elements map check. | 
| 183 static void GenerateFastArrayLoad(MacroAssembler* masm, | 183 static void GenerateFastArrayLoad(MacroAssembler* masm, | 
| 184                                   Register receiver, | 184                                   Register receiver, | 
| 185                                   Register key, | 185                                   Register key, | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 272   __ Branch(not_unique, ne, at, Operand(zero_reg)); | 272   __ Branch(not_unique, ne, at, Operand(zero_reg)); | 
| 273 | 273 | 
| 274   __ bind(&unique); | 274   __ bind(&unique); | 
| 275 } | 275 } | 
| 276 | 276 | 
| 277 | 277 | 
| 278 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 278 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 
| 279   // The return address is in lr. | 279   // The return address is in lr. | 
| 280   Register receiver = ReceiverRegister(); | 280   Register receiver = ReceiverRegister(); | 
| 281   Register name = NameRegister(); | 281   Register name = NameRegister(); | 
| 282   ASSERT(receiver.is(a1)); | 282   DCHECK(receiver.is(a1)); | 
| 283   ASSERT(name.is(a2)); | 283   DCHECK(name.is(a2)); | 
| 284 | 284 | 
| 285   // Probe the stub cache. | 285   // Probe the stub cache. | 
| 286   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 286   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 
| 287       Code::ComputeHandlerFlags(Code::LOAD_IC)); | 287       Code::ComputeHandlerFlags(Code::LOAD_IC)); | 
| 288   masm->isolate()->stub_cache()->GenerateProbe( | 288   masm->isolate()->stub_cache()->GenerateProbe( | 
| 289       masm, flags, receiver, name, a3, t0, t1, t2); | 289       masm, flags, receiver, name, a3, t0, t1, t2); | 
| 290 | 290 | 
| 291   // Cache miss: Jump to runtime. | 291   // Cache miss: Jump to runtime. | 
| 292   GenerateMiss(masm); | 292   GenerateMiss(masm); | 
| 293 } | 293 } | 
| 294 | 294 | 
| 295 | 295 | 
| 296 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 296 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 
| 297   Register dictionary = a0; | 297   Register dictionary = a0; | 
| 298   ASSERT(!dictionary.is(ReceiverRegister())); | 298   DCHECK(!dictionary.is(ReceiverRegister())); | 
| 299   ASSERT(!dictionary.is(NameRegister())); | 299   DCHECK(!dictionary.is(NameRegister())); | 
| 300 | 300 | 
| 301   Label slow; | 301   Label slow; | 
| 302 | 302 | 
| 303   __ lw(dictionary, | 303   __ lw(dictionary, | 
| 304         FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 304         FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 
| 305   GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, t0); | 305   GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), v0, a3, t0); | 
| 306   __ Ret(); | 306   __ Ret(); | 
| 307 | 307 | 
| 308   // Dictionary load failed, go slow (but don't miss). | 308   // Dictionary load failed, go slow (but don't miss). | 
| 309   __ bind(&slow); | 309   __ bind(&slow); | 
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 427           Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 427           Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 
| 428   __ Addu(scratch, backing_store, scratch); | 428   __ Addu(scratch, backing_store, scratch); | 
| 429   return MemOperand(scratch); | 429   return MemOperand(scratch); | 
| 430 } | 430 } | 
| 431 | 431 | 
| 432 | 432 | 
| 433 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 433 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 
| 434   // The return address is in ra. | 434   // The return address is in ra. | 
| 435   Register receiver = ReceiverRegister(); | 435   Register receiver = ReceiverRegister(); | 
| 436   Register key = NameRegister(); | 436   Register key = NameRegister(); | 
| 437   ASSERT(receiver.is(a1)); | 437   DCHECK(receiver.is(a1)); | 
| 438   ASSERT(key.is(a2)); | 438   DCHECK(key.is(a2)); | 
| 439 | 439 | 
| 440   Label slow, notin; | 440   Label slow, notin; | 
| 441   MemOperand mapped_location = | 441   MemOperand mapped_location = | 
| 442       GenerateMappedArgumentsLookup( | 442       GenerateMappedArgumentsLookup( | 
| 443           masm, receiver, key, a0, a3, t0, ¬in, &slow); | 443           masm, receiver, key, a0, a3, t0, ¬in, &slow); | 
| 444   __ Ret(USE_DELAY_SLOT); | 444   __ Ret(USE_DELAY_SLOT); | 
| 445   __ lw(v0, mapped_location); | 445   __ lw(v0, mapped_location); | 
| 446   __ bind(¬in); | 446   __ bind(¬in); | 
| 447   // The unmapped lookup expects that the parameter map is in a0. | 447   // The unmapped lookup expects that the parameter map is in a0. | 
| 448   MemOperand unmapped_location = | 448   MemOperand unmapped_location = | 
| 449       GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow); | 449       GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow); | 
| 450   __ lw(a0, unmapped_location); | 450   __ lw(a0, unmapped_location); | 
| 451   __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); | 451   __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); | 
| 452   __ Branch(&slow, eq, a0, Operand(a3)); | 452   __ Branch(&slow, eq, a0, Operand(a3)); | 
| 453   __ Ret(USE_DELAY_SLOT); | 453   __ Ret(USE_DELAY_SLOT); | 
| 454   __ mov(v0, a0); | 454   __ mov(v0, a0); | 
| 455   __ bind(&slow); | 455   __ bind(&slow); | 
| 456   GenerateMiss(masm); | 456   GenerateMiss(masm); | 
| 457 } | 457 } | 
| 458 | 458 | 
| 459 | 459 | 
| 460 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 460 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 
| 461   Register receiver = ReceiverRegister(); | 461   Register receiver = ReceiverRegister(); | 
| 462   Register key = NameRegister(); | 462   Register key = NameRegister(); | 
| 463   Register value = ValueRegister(); | 463   Register value = ValueRegister(); | 
| 464   ASSERT(value.is(a0)); | 464   DCHECK(value.is(a0)); | 
| 465 | 465 | 
| 466   Label slow, notin; | 466   Label slow, notin; | 
| 467   // Store address is returned in register (of MemOperand) mapped_location. | 467   // Store address is returned in register (of MemOperand) mapped_location. | 
| 468   MemOperand mapped_location = GenerateMappedArgumentsLookup( | 468   MemOperand mapped_location = GenerateMappedArgumentsLookup( | 
| 469       masm, receiver, key, a3, t0, t1, ¬in, &slow); | 469       masm, receiver, key, a3, t0, t1, ¬in, &slow); | 
| 470   __ sw(value, mapped_location); | 470   __ sw(value, mapped_location); | 
| 471   __ mov(t5, value); | 471   __ mov(t5, value); | 
| 472   ASSERT_EQ(mapped_location.offset(), 0); | 472   DCHECK_EQ(mapped_location.offset(), 0); | 
| 473   __ RecordWrite(a3, mapped_location.rm(), t5, | 473   __ RecordWrite(a3, mapped_location.rm(), t5, | 
| 474                  kRAHasNotBeenSaved, kDontSaveFPRegs); | 474                  kRAHasNotBeenSaved, kDontSaveFPRegs); | 
| 475   __ Ret(USE_DELAY_SLOT); | 475   __ Ret(USE_DELAY_SLOT); | 
| 476   __ mov(v0, value);  // (In delay slot) return the value stored in v0. | 476   __ mov(v0, value);  // (In delay slot) return the value stored in v0. | 
| 477   __ bind(¬in); | 477   __ bind(¬in); | 
| 478   // The unmapped lookup expects that the parameter map is in a3. | 478   // The unmapped lookup expects that the parameter map is in a3. | 
| 479   // Store address is returned in register (of MemOperand) unmapped_location. | 479   // Store address is returned in register (of MemOperand) unmapped_location. | 
| 480   MemOperand unmapped_location = | 480   MemOperand unmapped_location = | 
| 481       GenerateUnmappedArgumentsLookup(masm, key, a3, t0, &slow); | 481       GenerateUnmappedArgumentsLookup(masm, key, a3, t0, &slow); | 
| 482   __ sw(value, unmapped_location); | 482   __ sw(value, unmapped_location); | 
| 483   __ mov(t5, value); | 483   __ mov(t5, value); | 
| 484   ASSERT_EQ(unmapped_location.offset(), 0); | 484   DCHECK_EQ(unmapped_location.offset(), 0); | 
| 485   __ RecordWrite(a3, unmapped_location.rm(), t5, | 485   __ RecordWrite(a3, unmapped_location.rm(), t5, | 
| 486                  kRAHasNotBeenSaved, kDontSaveFPRegs); | 486                  kRAHasNotBeenSaved, kDontSaveFPRegs); | 
| 487   __ Ret(USE_DELAY_SLOT); | 487   __ Ret(USE_DELAY_SLOT); | 
| 488   __ mov(v0, a0);  // (In delay slot) return the value stored in v0. | 488   __ mov(v0, a0);  // (In delay slot) return the value stored in v0. | 
| 489   __ bind(&slow); | 489   __ bind(&slow); | 
| 490   GenerateMiss(masm); | 490   GenerateMiss(masm); | 
| 491 } | 491 } | 
| 492 | 492 | 
| 493 | 493 | 
| 494 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 494 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 506   __ TailCallExternalReference(ref, 2, 1); | 506   __ TailCallExternalReference(ref, 2, 1); | 
| 507 } | 507 } | 
| 508 | 508 | 
| 509 | 509 | 
| 510 // IC register specifications | 510 // IC register specifications | 
| 511 const Register LoadIC::ReceiverRegister() { return a1; } | 511 const Register LoadIC::ReceiverRegister() { return a1; } | 
| 512 const Register LoadIC::NameRegister() { return a2; } | 512 const Register LoadIC::NameRegister() { return a2; } | 
| 513 | 513 | 
| 514 | 514 | 
| 515 const Register LoadIC::SlotRegister() { | 515 const Register LoadIC::SlotRegister() { | 
| 516   ASSERT(FLAG_vector_ics); | 516   DCHECK(FLAG_vector_ics); | 
| 517   return a0; | 517   return a0; | 
| 518 } | 518 } | 
| 519 | 519 | 
| 520 | 520 | 
| 521 const Register LoadIC::VectorRegister() { | 521 const Register LoadIC::VectorRegister() { | 
| 522   ASSERT(FLAG_vector_ics); | 522   DCHECK(FLAG_vector_ics); | 
| 523   return a3; | 523   return a3; | 
| 524 } | 524 } | 
| 525 | 525 | 
| 526 | 526 | 
| 527 const Register StoreIC::ReceiverRegister() { return a1; } | 527 const Register StoreIC::ReceiverRegister() { return a1; } | 
| 528 const Register StoreIC::NameRegister() { return a2; } | 528 const Register StoreIC::NameRegister() { return a2; } | 
| 529 const Register StoreIC::ValueRegister() { return a0; } | 529 const Register StoreIC::ValueRegister() { return a0; } | 
| 530 | 530 | 
| 531 | 531 | 
| 532 const Register KeyedStoreIC::MapRegister() { | 532 const Register KeyedStoreIC::MapRegister() { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 543 } | 543 } | 
| 544 | 544 | 
| 545 | 545 | 
| 546 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 546 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 
| 547   // The return address is in ra. | 547   // The return address is in ra. | 
| 548   Label slow, check_name, index_smi, index_name, property_array_property; | 548   Label slow, check_name, index_smi, index_name, property_array_property; | 
| 549   Label probe_dictionary, check_number_dictionary; | 549   Label probe_dictionary, check_number_dictionary; | 
| 550 | 550 | 
| 551   Register key = NameRegister(); | 551   Register key = NameRegister(); | 
| 552   Register receiver = ReceiverRegister(); | 552   Register receiver = ReceiverRegister(); | 
| 553   ASSERT(key.is(a2)); | 553   DCHECK(key.is(a2)); | 
| 554   ASSERT(receiver.is(a1)); | 554   DCHECK(receiver.is(a1)); | 
| 555 | 555 | 
| 556   Isolate* isolate = masm->isolate(); | 556   Isolate* isolate = masm->isolate(); | 
| 557 | 557 | 
| 558   // Check that the key is a smi. | 558   // Check that the key is a smi. | 
| 559   __ JumpIfNotSmi(key, &check_name); | 559   __ JumpIfNotSmi(key, &check_name); | 
| 560   __ bind(&index_smi); | 560   __ bind(&index_smi); | 
| 561   // Now the key is known to be a smi. This place is also jumped to from below | 561   // Now the key is known to be a smi. This place is also jumped to from below | 
| 562   // where a numeric string is converted to a smi. | 562   // where a numeric string is converted to a smi. | 
| 563 | 563 | 
| 564   GenerateKeyedLoadReceiverCheck( | 564   GenerateKeyedLoadReceiverCheck( | 
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 714 | 714 | 
| 715 | 715 | 
| 716 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 716 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 
| 717   // Return address is in ra. | 717   // Return address is in ra. | 
| 718   Label miss; | 718   Label miss; | 
| 719 | 719 | 
| 720   Register receiver = ReceiverRegister(); | 720   Register receiver = ReceiverRegister(); | 
| 721   Register index = NameRegister(); | 721   Register index = NameRegister(); | 
| 722   Register scratch = a3; | 722   Register scratch = a3; | 
| 723   Register result = v0; | 723   Register result = v0; | 
| 724   ASSERT(!scratch.is(receiver) && !scratch.is(index)); | 724   DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 
| 725 | 725 | 
| 726   StringCharAtGenerator char_at_generator(receiver, | 726   StringCharAtGenerator char_at_generator(receiver, | 
| 727                                           index, | 727                                           index, | 
| 728                                           scratch, | 728                                           scratch, | 
| 729                                           result, | 729                                           result, | 
| 730                                           &miss,  // When not a string. | 730                                           &miss,  // When not a string. | 
| 731                                           &miss,  // When not a number. | 731                                           &miss,  // When not a number. | 
| 732                                           &miss,  // When index out of range. | 732                                           &miss,  // When index out of range. | 
| 733                                           STRING_INDEX_IS_ARRAY_INDEX); | 733                                           STRING_INDEX_IS_ARRAY_INDEX); | 
| 734   char_at_generator.GenerateFast(masm); | 734   char_at_generator.GenerateFast(masm); | 
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 934   //  -- ra     : return address | 934   //  -- ra     : return address | 
| 935   // ----------------------------------- | 935   // ----------------------------------- | 
| 936   Label slow, fast_object, fast_object_grow; | 936   Label slow, fast_object, fast_object_grow; | 
| 937   Label fast_double, fast_double_grow; | 937   Label fast_double, fast_double_grow; | 
| 938   Label array, extra, check_if_double_array; | 938   Label array, extra, check_if_double_array; | 
| 939 | 939 | 
| 940   // Register usage. | 940   // Register usage. | 
| 941   Register value = ValueRegister(); | 941   Register value = ValueRegister(); | 
| 942   Register key = NameRegister(); | 942   Register key = NameRegister(); | 
| 943   Register receiver = ReceiverRegister(); | 943   Register receiver = ReceiverRegister(); | 
| 944   ASSERT(value.is(a0)); | 944   DCHECK(value.is(a0)); | 
| 945   Register receiver_map = a3; | 945   Register receiver_map = a3; | 
| 946   Register elements_map = t2; | 946   Register elements_map = t2; | 
| 947   Register elements = t3;  // Elements array of the receiver. | 947   Register elements = t3;  // Elements array of the receiver. | 
| 948   // t0 and t1 are used as general scratch registers. | 948   // t0 and t1 are used as general scratch registers. | 
| 949 | 949 | 
| 950   // Check that the key is a smi. | 950   // Check that the key is a smi. | 
| 951   __ JumpIfNotSmi(key, &slow); | 951   __ JumpIfNotSmi(key, &slow); | 
| 952   // Check that the object isn't a smi. | 952   // Check that the object isn't a smi. | 
| 953   __ JumpIfSmi(receiver, &slow); | 953   __ JumpIfSmi(receiver, &slow); | 
| 954   // Get the map of the object. | 954   // Get the map of the object. | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1022 | 1022 | 
| 1023 | 1023 | 
| 1024 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 1024 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 
| 1025   // Return address is in ra. | 1025   // Return address is in ra. | 
| 1026   Label slow; | 1026   Label slow; | 
| 1027 | 1027 | 
| 1028   Register receiver = ReceiverRegister(); | 1028   Register receiver = ReceiverRegister(); | 
| 1029   Register key = NameRegister(); | 1029   Register key = NameRegister(); | 
| 1030   Register scratch1 = a3; | 1030   Register scratch1 = a3; | 
| 1031   Register scratch2 = t0; | 1031   Register scratch2 = t0; | 
| 1032   ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); | 1032   DCHECK(!scratch1.is(receiver) && !scratch1.is(key)); | 
| 1033   ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); | 1033   DCHECK(!scratch2.is(receiver) && !scratch2.is(key)); | 
| 1034 | 1034 | 
| 1035   // Check that the receiver isn't a smi. | 1035   // Check that the receiver isn't a smi. | 
| 1036   __ JumpIfSmi(receiver, &slow); | 1036   __ JumpIfSmi(receiver, &slow); | 
| 1037 | 1037 | 
| 1038   // Check that the key is an array index, that is Uint32. | 1038   // Check that the key is an array index, that is Uint32. | 
| 1039   __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); | 1039   __ And(t0, key, Operand(kSmiTagMask | kSmiSignMask)); | 
| 1040   __ Branch(&slow, ne, t0, Operand(zero_reg)); | 1040   __ Branch(&slow, ne, t0, Operand(zero_reg)); | 
| 1041 | 1041 | 
| 1042   // Get the map of the receiver. | 1042   // Get the map of the receiver. | 
| 1043   __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1043   __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1091   ExternalReference ref = | 1091   ExternalReference ref = | 
| 1092       ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 1092       ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 
| 1093 | 1093 | 
| 1094   __ TailCallExternalReference(ref, 3, 1); | 1094   __ TailCallExternalReference(ref, 3, 1); | 
| 1095 } | 1095 } | 
| 1096 | 1096 | 
| 1097 | 1097 | 
| 1098 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1098 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 
| 1099   Register receiver = ReceiverRegister(); | 1099   Register receiver = ReceiverRegister(); | 
| 1100   Register name = NameRegister(); | 1100   Register name = NameRegister(); | 
| 1101   ASSERT(receiver.is(a1)); | 1101   DCHECK(receiver.is(a1)); | 
| 1102   ASSERT(name.is(a2)); | 1102   DCHECK(name.is(a2)); | 
| 1103   ASSERT(ValueRegister().is(a0)); | 1103   DCHECK(ValueRegister().is(a0)); | 
| 1104 | 1104 | 
| 1105   // Get the receiver from the stack and probe the stub cache. | 1105   // Get the receiver from the stack and probe the stub cache. | 
| 1106   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 1106   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 
| 1107       Code::ComputeHandlerFlags(Code::STORE_IC)); | 1107       Code::ComputeHandlerFlags(Code::STORE_IC)); | 
| 1108   masm->isolate()->stub_cache()->GenerateProbe( | 1108   masm->isolate()->stub_cache()->GenerateProbe( | 
| 1109       masm, flags, receiver, name, a3, t0, t1, t2); | 1109       masm, flags, receiver, name, a3, t0, t1, t2); | 
| 1110 | 1110 | 
| 1111   // Cache miss: Jump to runtime. | 1111   // Cache miss: Jump to runtime. | 
| 1112   GenerateMiss(masm); | 1112   GenerateMiss(masm); | 
| 1113 } | 1113 } | 
| 1114 | 1114 | 
| 1115 | 1115 | 
| 1116 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1116 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 
| 1117   __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); | 1117   __ Push(ReceiverRegister(), NameRegister(), ValueRegister()); | 
| 1118   // Perform tail call to the entry. | 1118   // Perform tail call to the entry. | 
| 1119   ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), | 1119   ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss), | 
| 1120                                             masm->isolate()); | 1120                                             masm->isolate()); | 
| 1121   __ TailCallExternalReference(ref, 3, 1); | 1121   __ TailCallExternalReference(ref, 3, 1); | 
| 1122 } | 1122 } | 
| 1123 | 1123 | 
| 1124 | 1124 | 
| 1125 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1125 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 
| 1126   Label miss; | 1126   Label miss; | 
| 1127   Register receiver = ReceiverRegister(); | 1127   Register receiver = ReceiverRegister(); | 
| 1128   Register name = NameRegister(); | 1128   Register name = NameRegister(); | 
| 1129   Register value = ValueRegister(); | 1129   Register value = ValueRegister(); | 
| 1130   Register dictionary = a3; | 1130   Register dictionary = a3; | 
| 1131   ASSERT(receiver.is(a1)); | 1131   DCHECK(receiver.is(a1)); | 
| 1132   ASSERT(name.is(a2)); | 1132   DCHECK(name.is(a2)); | 
| 1133   ASSERT(value.is(a0)); | 1133   DCHECK(value.is(a0)); | 
| 1134 | 1134 | 
| 1135   __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 1135   __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
| 1136 | 1136 | 
| 1137   GenerateDictionaryStore(masm, &miss, dictionary, name, value, t0, t1); | 1137   GenerateDictionaryStore(masm, &miss, dictionary, name, value, t0, t1); | 
| 1138   Counters* counters = masm->isolate()->counters(); | 1138   Counters* counters = masm->isolate()->counters(); | 
| 1139   __ IncrementCounter(counters->store_normal_hit(), 1, t0, t1); | 1139   __ IncrementCounter(counters->store_normal_hit(), 1, t0, t1); | 
| 1140   __ Ret(); | 1140   __ Ret(); | 
| 1141 | 1141 | 
| 1142   __ bind(&miss); | 1142   __ bind(&miss); | 
| 1143   __ IncrementCounter(counters->store_normal_miss(), 1, t0, t1); | 1143   __ IncrementCounter(counters->store_normal_miss(), 1, t0, t1); | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1229   // Enabling by changing from | 1229   // Enabling by changing from | 
| 1230   //   andi at, rx, 0 | 1230   //   andi at, rx, 0 | 
| 1231   //   Branch <target>, eq, at, Operand(zero_reg) | 1231   //   Branch <target>, eq, at, Operand(zero_reg) | 
| 1232   // to: | 1232   // to: | 
| 1233   //   andi at, rx, #kSmiTagMask | 1233   //   andi at, rx, #kSmiTagMask | 
| 1234   //   Branch <target>, ne, at, Operand(zero_reg) | 1234   //   Branch <target>, ne, at, Operand(zero_reg) | 
| 1235   // and vice-versa to be disabled again. | 1235   // and vice-versa to be disabled again. | 
| 1236   CodePatcher patcher(patch_address, 2); | 1236   CodePatcher patcher(patch_address, 2); | 
| 1237   Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); | 1237   Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); | 
| 1238   if (check == ENABLE_INLINED_SMI_CHECK) { | 1238   if (check == ENABLE_INLINED_SMI_CHECK) { | 
| 1239     ASSERT(Assembler::IsAndImmediate(instr_at_patch)); | 1239     DCHECK(Assembler::IsAndImmediate(instr_at_patch)); | 
| 1240     ASSERT_EQ(0, Assembler::GetImmediate16(instr_at_patch)); | 1240     DCHECK_EQ(0, Assembler::GetImmediate16(instr_at_patch)); | 
| 1241     patcher.masm()->andi(at, reg, kSmiTagMask); | 1241     patcher.masm()->andi(at, reg, kSmiTagMask); | 
| 1242   } else { | 1242   } else { | 
| 1243     ASSERT(check == DISABLE_INLINED_SMI_CHECK); | 1243     DCHECK(check == DISABLE_INLINED_SMI_CHECK); | 
| 1244     ASSERT(Assembler::IsAndImmediate(instr_at_patch)); | 1244     DCHECK(Assembler::IsAndImmediate(instr_at_patch)); | 
| 1245     patcher.masm()->andi(at, reg, 0); | 1245     patcher.masm()->andi(at, reg, 0); | 
| 1246   } | 1246   } | 
| 1247   ASSERT(Assembler::IsBranch(branch_instr)); | 1247   DCHECK(Assembler::IsBranch(branch_instr)); | 
| 1248   if (Assembler::IsBeq(branch_instr)) { | 1248   if (Assembler::IsBeq(branch_instr)) { | 
| 1249     patcher.ChangeBranchCondition(ne); | 1249     patcher.ChangeBranchCondition(ne); | 
| 1250   } else { | 1250   } else { | 
| 1251     ASSERT(Assembler::IsBne(branch_instr)); | 1251     DCHECK(Assembler::IsBne(branch_instr)); | 
| 1252     patcher.ChangeBranchCondition(eq); | 1252     patcher.ChangeBranchCondition(eq); | 
| 1253   } | 1253   } | 
| 1254 } | 1254 } | 
| 1255 | 1255 | 
| 1256 | 1256 | 
| 1257 } }  // namespace v8::internal | 1257 } }  // namespace v8::internal | 
| 1258 | 1258 | 
| 1259 #endif  // V8_TARGET_ARCH_MIPS | 1259 #endif  // V8_TARGET_ARCH_MIPS | 
| OLD | NEW | 
|---|