| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 } | 282 } |
| 283 | 283 |
| 284 | 284 |
| 285 // A register that isn't one of the parameters to the load ic. | 285 // A register that isn't one of the parameters to the load ic. |
| 286 static const Register LoadIC_TempRegister() { return r3; } | 286 static const Register LoadIC_TempRegister() { return r3; } |
| 287 | 287 |
| 288 | 288 |
| 289 static void LoadIC_PushArgs(MacroAssembler* masm) { | 289 static void LoadIC_PushArgs(MacroAssembler* masm) { |
| 290 Register receiver = LoadDescriptor::ReceiverRegister(); | 290 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 291 Register name = LoadDescriptor::NameRegister(); | 291 Register name = LoadDescriptor::NameRegister(); |
| 292 if (FLAG_vector_ics) { | 292 Register slot = VectorLoadICDescriptor::SlotRegister(); |
| 293 Register slot = VectorLoadICDescriptor::SlotRegister(); | 293 Register vector = VectorLoadICDescriptor::VectorRegister(); |
| 294 Register vector = VectorLoadICDescriptor::VectorRegister(); | |
| 295 | 294 |
| 296 __ Push(receiver, name, slot, vector); | 295 __ Push(receiver, name, slot, vector); |
| 297 } else { | |
| 298 __ Push(receiver, name); | |
| 299 } | |
| 300 } | 296 } |
| 301 | 297 |
| 302 | 298 |
| 303 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 299 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
| 304 // The return address is in lr. | 300 // The return address is in lr. |
| 305 Isolate* isolate = masm->isolate(); | 301 Isolate* isolate = masm->isolate(); |
| 306 | 302 |
| 307 DCHECK(!FLAG_vector_ics || | 303 DCHECK(!AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(), |
| 308 !AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(), | |
| 309 VectorLoadICDescriptor::VectorRegister())); | 304 VectorLoadICDescriptor::VectorRegister())); |
| 310 __ IncrementCounter(isolate->counters()->load_miss(), 1, r4, r5); | 305 __ IncrementCounter(isolate->counters()->load_miss(), 1, r4, r5); |
| 311 | 306 |
| 312 LoadIC_PushArgs(masm); | 307 LoadIC_PushArgs(masm); |
| 313 | 308 |
| 314 // Perform tail call to the entry. | 309 // Perform tail call to the entry. |
| 315 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); | 310 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); |
| 316 int arg_count = FLAG_vector_ics ? 4 : 2; | 311 int arg_count = 4; |
| 317 __ TailCallExternalReference(ref, arg_count, 1); | 312 __ TailCallExternalReference(ref, arg_count, 1); |
| 318 } | 313 } |
| 319 | 314 |
| 320 | 315 |
| 321 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 316 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
| 322 // The return address is in lr. | 317 // The return address is in lr. |
| 323 | 318 |
| 324 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); | 319 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); |
| 325 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); | 320 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); |
| 326 | 321 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 __ Ret(); | 429 __ Ret(); |
| 435 __ bind(&slow); | 430 __ bind(&slow); |
| 436 GenerateMiss(masm); | 431 GenerateMiss(masm); |
| 437 } | 432 } |
| 438 | 433 |
| 439 | 434 |
| 440 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 435 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
| 441 // The return address is in lr. | 436 // The return address is in lr. |
| 442 Isolate* isolate = masm->isolate(); | 437 Isolate* isolate = masm->isolate(); |
| 443 | 438 |
| 444 DCHECK(!FLAG_vector_ics || | 439 DCHECK(!AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(), |
| 445 !AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(), | |
| 446 VectorLoadICDescriptor::VectorRegister())); | 440 VectorLoadICDescriptor::VectorRegister())); |
| 447 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5); | 441 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5); |
| 448 | 442 |
| 449 LoadIC_PushArgs(masm); | 443 LoadIC_PushArgs(masm); |
| 450 | 444 |
| 451 // Perform tail call to the entry. | 445 // Perform tail call to the entry. |
| 452 ExternalReference ref = | 446 ExternalReference ref = |
| 453 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); | 447 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); |
| 454 int arg_count = FLAG_vector_ics ? 4 : 2; | 448 int arg_count = 4; |
| 455 __ TailCallExternalReference(ref, arg_count, 1); | 449 __ TailCallExternalReference(ref, arg_count, 1); |
| 456 } | 450 } |
| 457 | 451 |
| 458 | 452 |
| 459 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 453 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
| 460 // The return address is in lr. | 454 // The return address is in lr. |
| 461 | 455 |
| 462 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); | 456 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); |
| 463 | 457 |
| 464 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 458 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 Map::kHasNamedInterceptor, &slow); | 514 Map::kHasNamedInterceptor, &slow); |
| 521 | 515 |
| 522 // If the receiver is a fast-case object, check the stub cache. Otherwise | 516 // If the receiver is a fast-case object, check the stub cache. Otherwise |
| 523 // probe the dictionary. | 517 // probe the dictionary. |
| 524 __ ldr(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 518 __ ldr(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 525 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); | 519 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); |
| 526 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 520 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
| 527 __ cmp(r4, ip); | 521 __ cmp(r4, ip); |
| 528 __ b(eq, &probe_dictionary); | 522 __ b(eq, &probe_dictionary); |
| 529 | 523 |
| 530 | 524 // The handlers in the stub cache expect a vector and slot. Since we won't |
| 531 if (FLAG_vector_ics) { | 525 // change the IC from any downstream misses, a dummy vector can be used. |
| 532 // When vector ics are in use, the handlers in the stub cache expect a | 526 Register vector = VectorLoadICDescriptor::VectorRegister(); |
| 533 // vector and slot. Since we won't change the IC from any downstream | 527 Register slot = VectorLoadICDescriptor::SlotRegister(); |
| 534 // misses, a dummy vector can be used. | 528 DCHECK(!AreAliased(vector, slot, r4, r5, r6, r9)); |
| 535 Register vector = VectorLoadICDescriptor::VectorRegister(); | 529 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast( |
| 536 Register slot = VectorLoadICDescriptor::SlotRegister(); | 530 masm->isolate()->factory()->keyed_load_dummy_vector()); |
| 537 DCHECK(!AreAliased(vector, slot, r4, r5, r6, r9)); | 531 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0)); |
| 538 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast( | 532 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex); |
| 539 masm->isolate()->factory()->keyed_load_dummy_vector()); | 533 __ mov(slot, Operand(Smi::FromInt(int_slot))); |
| 540 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0)); | |
| 541 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex); | |
| 542 __ mov(slot, Operand(Smi::FromInt(int_slot))); | |
| 543 } | |
| 544 | 534 |
| 545 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 535 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 546 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 536 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 547 masm->isolate()->stub_cache()->GenerateProbe( | 537 masm->isolate()->stub_cache()->GenerateProbe( |
| 548 masm, Code::KEYED_LOAD_IC, flags, false, receiver, key, r4, r5, r6, r9); | 538 masm, Code::KEYED_LOAD_IC, flags, false, receiver, key, r4, r5, r6, r9); |
| 549 // Cache miss. | 539 // Cache miss. |
| 550 GenerateMiss(masm); | 540 GenerateMiss(masm); |
| 551 | 541 |
| 552 // Do a quick inline probe of the receiver's dictionary, if it | 542 // Do a quick inline probe of the receiver's dictionary, if it |
| 553 // exists. | 543 // exists. |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 patcher.EmitCondition(ne); | 971 patcher.EmitCondition(ne); |
| 982 } else { | 972 } else { |
| 983 DCHECK(Assembler::GetCondition(branch_instr) == ne); | 973 DCHECK(Assembler::GetCondition(branch_instr) == ne); |
| 984 patcher.EmitCondition(eq); | 974 patcher.EmitCondition(eq); |
| 985 } | 975 } |
| 986 } | 976 } |
| 987 } | 977 } |
| 988 } // namespace v8::internal | 978 } // namespace v8::internal |
| 989 | 979 |
| 990 #endif // V8_TARGET_ARCH_ARM | 980 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |