| 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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
| 9 #include "src/ic/ic-compiler.h" | 9 #include "src/ic/ic-compiler.h" |
| 10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 __ Push(receiver, name, slot, vector); | 297 __ Push(receiver, name, slot, vector); |
| 298 } | 298 } |
| 299 | 299 |
| 300 | 300 |
| 301 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 301 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
| 302 // The return address is in lr. | 302 // The return address is in lr. |
| 303 Isolate* isolate = masm->isolate(); | 303 Isolate* isolate = masm->isolate(); |
| 304 | 304 |
| 305 DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::SlotRegister(), | 305 DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::SlotRegister(), |
| 306 LoadWithVectorDescriptor::VectorRegister())); | 306 LoadWithVectorDescriptor::VectorRegister())); |
| 307 __ IncrementCounter(isolate->counters()->load_miss(), 1, r4, r5); | 307 __ IncrementCounter(isolate->counters()->ic_load_miss(), 1, r4, r5); |
| 308 | 308 |
| 309 LoadIC_PushArgs(masm); | 309 LoadIC_PushArgs(masm); |
| 310 | 310 |
| 311 // Perform tail call to the entry. | 311 // Perform tail call to the entry. |
| 312 __ TailCallRuntime(Runtime::kLoadIC_Miss); | 312 __ TailCallRuntime(Runtime::kLoadIC_Miss); |
| 313 } | 313 } |
| 314 | 314 |
| 315 | 315 |
| 316 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm, | 316 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm, |
| 317 LanguageMode language_mode) { | 317 LanguageMode language_mode) { |
| 318 // The return address is in lr. | 318 // The return address is in lr. |
| 319 | 319 |
| 320 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); | 320 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); |
| 321 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); | 321 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); |
| 322 | 322 |
| 323 // Do tail-call to runtime routine. | 323 // Do tail-call to runtime routine. |
| 324 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kGetPropertyStrong | 324 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kGetPropertyStrong |
| 325 : Runtime::kGetProperty); | 325 : Runtime::kGetProperty); |
| 326 } | 326 } |
| 327 | 327 |
| 328 | 328 |
| 329 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 329 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
| 330 // The return address is in lr. | 330 // The return address is in lr. |
| 331 Isolate* isolate = masm->isolate(); | 331 Isolate* isolate = masm->isolate(); |
| 332 | 332 |
| 333 DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::SlotRegister(), | 333 DCHECK(!AreAliased(r4, r5, LoadWithVectorDescriptor::SlotRegister(), |
| 334 LoadWithVectorDescriptor::VectorRegister())); | 334 LoadWithVectorDescriptor::VectorRegister())); |
| 335 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5); | 335 __ IncrementCounter(isolate->counters()->ic_keyed_load_miss(), 1, r4, r5); |
| 336 | 336 |
| 337 LoadIC_PushArgs(masm); | 337 LoadIC_PushArgs(masm); |
| 338 | 338 |
| 339 // Perform tail call to the entry. | 339 // Perform tail call to the entry. |
| 340 __ TailCallRuntime(Runtime::kKeyedLoadIC_Miss); | 340 __ TailCallRuntime(Runtime::kKeyedLoadIC_Miss); |
| 341 } | 341 } |
| 342 | 342 |
| 343 | 343 |
| 344 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm, | 344 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm, |
| 345 LanguageMode language_mode) { | 345 LanguageMode language_mode) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 374 // where a numeric string is converted to a smi. | 374 // where a numeric string is converted to a smi. |
| 375 | 375 |
| 376 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3, | 376 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3, |
| 377 Map::kHasIndexedInterceptor, &slow); | 377 Map::kHasIndexedInterceptor, &slow); |
| 378 | 378 |
| 379 // Check the receiver's map to see if it has fast elements. | 379 // Check the receiver's map to see if it has fast elements. |
| 380 __ CheckFastElements(r0, r3, &check_number_dictionary); | 380 __ CheckFastElements(r0, r3, &check_number_dictionary); |
| 381 | 381 |
| 382 GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow, | 382 GenerateFastArrayLoad(masm, receiver, key, r0, r3, r4, r0, &slow, |
| 383 language_mode); | 383 language_mode); |
| 384 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3); | 384 __ IncrementCounter(isolate->counters()->ic_keyed_load_generic_smi(), 1, r4, |
| 385 r3); |
| 385 __ Ret(); | 386 __ Ret(); |
| 386 | 387 |
| 387 __ bind(&check_number_dictionary); | 388 __ bind(&check_number_dictionary); |
| 388 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 389 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| 389 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); | 390 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); |
| 390 | 391 |
| 391 // Check whether the elements is a number dictionary. | 392 // Check whether the elements is a number dictionary. |
| 392 // r3: elements map | 393 // r3: elements map |
| 393 // r4: elements | 394 // r4: elements |
| 394 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 395 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
| 395 __ cmp(r3, ip); | 396 __ cmp(r3, ip); |
| 396 __ b(ne, &slow); | 397 __ b(ne, &slow); |
| 397 __ SmiUntag(r0, key); | 398 __ SmiUntag(r0, key); |
| 398 __ LoadFromNumberDictionary(&slow, r4, key, r0, r0, r3, r5); | 399 __ LoadFromNumberDictionary(&slow, r4, key, r0, r0, r3, r5); |
| 399 __ Ret(); | 400 __ Ret(); |
| 400 | 401 |
| 401 // Slow case, key and receiver still in r2 and r1. | 402 // Slow case, key and receiver still in r2 and r1. |
| 402 __ bind(&slow); | 403 __ bind(&slow); |
| 403 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r4, | 404 __ IncrementCounter(isolate->counters()->ic_keyed_load_generic_slow(), 1, r4, |
| 404 r3); | 405 r3); |
| 405 GenerateRuntimeGetProperty(masm, language_mode); | 406 GenerateRuntimeGetProperty(masm, language_mode); |
| 406 | 407 |
| 407 __ bind(&check_name); | 408 __ bind(&check_name); |
| 408 GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow); | 409 GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow); |
| 409 | 410 |
| 410 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3, | 411 GenerateKeyedLoadReceiverCheck(masm, receiver, r0, r3, |
| 411 Map::kHasNamedInterceptor, &slow); | 412 Map::kHasNamedInterceptor, &slow); |
| 412 | 413 |
| 413 // If the receiver is a fast-case object, check the stub cache. Otherwise | 414 // If the receiver is a fast-case object, check the stub cache. Otherwise |
| (...skipping 25 matching lines...) Expand all Loading... |
| 439 | 440 |
| 440 // Do a quick inline probe of the receiver's dictionary, if it | 441 // Do a quick inline probe of the receiver's dictionary, if it |
| 441 // exists. | 442 // exists. |
| 442 __ bind(&probe_dictionary); | 443 __ bind(&probe_dictionary); |
| 443 // r3: elements | 444 // r3: elements |
| 444 __ ldr(r0, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 445 __ ldr(r0, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 445 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); | 446 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); |
| 446 GenerateGlobalInstanceTypeCheck(masm, r0, &slow); | 447 GenerateGlobalInstanceTypeCheck(masm, r0, &slow); |
| 447 // Load the property to r0. | 448 // Load the property to r0. |
| 448 GenerateDictionaryLoad(masm, &slow, r3, key, r0, r5, r4); | 449 GenerateDictionaryLoad(masm, &slow, r3, key, r0, r5, r4); |
| 449 __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1, r4, | 450 __ IncrementCounter(isolate->counters()->ic_keyed_load_generic_symbol(), 1, |
| 450 r3); | 451 r4, r3); |
| 451 __ Ret(); | 452 __ Ret(); |
| 452 | 453 |
| 453 __ bind(&index_name); | 454 __ bind(&index_name); |
| 454 __ IndexFromHash(r3, key); | 455 __ IndexFromHash(r3, key); |
| 455 // Now jump to the place where smi keys are handled. | 456 // Now jump to the place where smi keys are handled. |
| 456 __ jmp(&index_smi); | 457 __ jmp(&index_smi); |
| 457 } | 458 } |
| 458 | 459 |
| 459 | 460 |
| 460 static void StoreIC_PushArgs(MacroAssembler* masm) { | 461 static void StoreIC_PushArgs(MacroAssembler* masm) { |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 DCHECK(receiver.is(r1)); | 787 DCHECK(receiver.is(r1)); |
| 787 DCHECK(name.is(r2)); | 788 DCHECK(name.is(r2)); |
| 788 DCHECK(value.is(r0)); | 789 DCHECK(value.is(r0)); |
| 789 DCHECK(VectorStoreICDescriptor::VectorRegister().is(r3)); | 790 DCHECK(VectorStoreICDescriptor::VectorRegister().is(r3)); |
| 790 DCHECK(VectorStoreICDescriptor::SlotRegister().is(r4)); | 791 DCHECK(VectorStoreICDescriptor::SlotRegister().is(r4)); |
| 791 | 792 |
| 792 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 793 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 793 | 794 |
| 794 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r6, r9); | 795 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r6, r9); |
| 795 Counters* counters = masm->isolate()->counters(); | 796 Counters* counters = masm->isolate()->counters(); |
| 796 __ IncrementCounter(counters->store_normal_hit(), 1, r6, r9); | 797 __ IncrementCounter(counters->ic_store_normal_hit(), 1, r6, r9); |
| 797 __ Ret(); | 798 __ Ret(); |
| 798 | 799 |
| 799 __ bind(&miss); | 800 __ bind(&miss); |
| 800 __ IncrementCounter(counters->store_normal_miss(), 1, r6, r9); | 801 __ IncrementCounter(counters->ic_store_normal_miss(), 1, r6, r9); |
| 801 GenerateMiss(masm); | 802 GenerateMiss(masm); |
| 802 } | 803 } |
| 803 | 804 |
| 804 | 805 |
| 805 #undef __ | 806 #undef __ |
| 806 | 807 |
| 807 | 808 |
| 808 Condition CompareIC::ComputeCondition(Token::Value op) { | 809 Condition CompareIC::ComputeCondition(Token::Value op) { |
| 809 switch (op) { | 810 switch (op) { |
| 810 case Token::EQ_STRICT: | 811 case Token::EQ_STRICT: |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 patcher.EmitCondition(ne); | 895 patcher.EmitCondition(ne); |
| 895 } else { | 896 } else { |
| 896 DCHECK(Assembler::GetCondition(branch_instr) == ne); | 897 DCHECK(Assembler::GetCondition(branch_instr) == ne); |
| 897 patcher.EmitCondition(eq); | 898 patcher.EmitCondition(eq); |
| 898 } | 899 } |
| 899 } | 900 } |
| 900 } // namespace internal | 901 } // namespace internal |
| 901 } // namespace v8 | 902 } // namespace v8 |
| 902 | 903 |
| 903 #endif // V8_TARGET_ARCH_ARM | 904 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |