OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 __ tst(hash, Operand(kIsSymbolMask)); | 375 __ tst(hash, Operand(kIsSymbolMask)); |
376 __ b(eq, not_symbol); | 376 __ b(eq, not_symbol); |
377 } | 377 } |
378 | 378 |
379 | 379 |
380 // Defined in ic.cc. | 380 // Defined in ic.cc. |
381 Object* CallIC_Miss(Arguments args); | 381 Object* CallIC_Miss(Arguments args); |
382 | 382 |
383 // The generated code does not accept smi keys. | 383 // The generated code does not accept smi keys. |
384 // The generated code falls through if both probes miss. | 384 // The generated code falls through if both probes miss. |
385 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, | 385 void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
386 int argc, | 386 int argc, |
387 Code::Kind kind, | 387 Code::Kind kind, |
388 Code::ExtraICState extra_ic_state) { | 388 Code::ExtraICState extra_state) { |
389 // ----------- S t a t e ------------- | 389 // ----------- S t a t e ------------- |
390 // -- r1 : receiver | 390 // -- r1 : receiver |
391 // -- r2 : name | 391 // -- r2 : name |
392 // ----------------------------------- | 392 // ----------------------------------- |
393 Label number, non_number, non_string, boolean, probe, miss; | 393 Label number, non_number, non_string, boolean, probe, miss; |
394 | 394 |
395 // Probe the stub cache. | 395 // Probe the stub cache. |
396 Code::Flags flags = Code::ComputeFlags(kind, | 396 Code::Flags flags = Code::ComputeFlags(kind, |
397 MONOMORPHIC, | 397 MONOMORPHIC, |
398 extra_ic_state, | 398 extra_state, |
399 NORMAL, | 399 NORMAL, |
400 argc); | 400 argc); |
401 Isolate::Current()->stub_cache()->GenerateProbe( | 401 Isolate::Current()->stub_cache()->GenerateProbe( |
402 masm, flags, r1, r2, r3, r4, r5); | 402 masm, flags, r1, r2, r3, r4, r5); |
403 | 403 |
404 // If the stub cache probing failed, the receiver might be a value. | 404 // If the stub cache probing failed, the receiver might be a value. |
405 // For value objects, we use the map of the prototype objects for | 405 // For value objects, we use the map of the prototype objects for |
406 // the corresponding JSValue for the cache and that is what we need | 406 // the corresponding JSValue for the cache and that is what we need |
407 // to probe. | 407 // to probe. |
408 // | 408 // |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE); | 457 __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE); |
458 __ b(ne, miss); | 458 __ b(ne, miss); |
459 | 459 |
460 // Invoke the function. | 460 // Invoke the function. |
461 ParameterCount actual(argc); | 461 ParameterCount actual(argc); |
462 __ InvokeFunction(r1, actual, JUMP_FUNCTION, | 462 __ InvokeFunction(r1, actual, JUMP_FUNCTION, |
463 NullCallWrapper(), CALL_AS_METHOD); | 463 NullCallWrapper(), CALL_AS_METHOD); |
464 } | 464 } |
465 | 465 |
466 | 466 |
467 static void GenerateCallNormal(MacroAssembler* masm, int argc) { | 467 void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) { |
468 // ----------- S t a t e ------------- | 468 // ----------- S t a t e ------------- |
469 // -- r2 : name | 469 // -- r2 : name |
470 // -- lr : return address | 470 // -- lr : return address |
471 // ----------------------------------- | 471 // ----------------------------------- |
472 Label miss; | 472 Label miss; |
473 | 473 |
474 // Get the receiver of the function from the stack into r1. | 474 // Get the receiver of the function from the stack into r1. |
475 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 475 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
476 | 476 |
477 GenerateStringDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss); | 477 GenerateStringDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss); |
478 | 478 |
479 // r0: elements | 479 // r0: elements |
480 // Search the dictionary - put result in register r1. | 480 // Search the dictionary - put result in register r1. |
481 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4); | 481 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4); |
482 | 482 |
483 GenerateFunctionTailCall(masm, argc, &miss, r4); | 483 GenerateFunctionTailCall(masm, argc, &miss, r4); |
484 | 484 |
485 __ bind(&miss); | 485 __ bind(&miss); |
486 } | 486 } |
487 | 487 |
488 | 488 |
489 static void GenerateCallMiss(MacroAssembler* masm, | 489 void CallICBase::GenerateMiss(MacroAssembler* masm, |
490 int argc, | 490 int argc, |
491 IC::UtilityId id, | 491 IC::UtilityId id, |
492 Code::ExtraICState extra_ic_state) { | 492 Code::ExtraICState extra_state) { |
493 // ----------- S t a t e ------------- | 493 // ----------- S t a t e ------------- |
494 // -- r2 : name | 494 // -- r2 : name |
495 // -- lr : return address | 495 // -- lr : return address |
496 // ----------------------------------- | 496 // ----------------------------------- |
497 Isolate* isolate = masm->isolate(); | 497 Isolate* isolate = masm->isolate(); |
498 | 498 |
499 if (id == IC::kCallIC_Miss) { | 499 if (id == IC::kCallIC_Miss) { |
500 __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4); | 500 __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4); |
501 } else { | 501 } else { |
502 __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4); | 502 __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 __ b(ne, &invoke); | 534 __ b(ne, &invoke); |
535 | 535 |
536 // Patch the receiver on the stack. | 536 // Patch the receiver on the stack. |
537 __ bind(&global); | 537 __ bind(&global); |
538 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); | 538 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); |
539 __ str(r2, MemOperand(sp, argc * kPointerSize)); | 539 __ str(r2, MemOperand(sp, argc * kPointerSize)); |
540 __ bind(&invoke); | 540 __ bind(&invoke); |
541 } | 541 } |
542 | 542 |
543 // Invoke the function. | 543 // Invoke the function. |
544 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) | 544 CallKind call_kind = CallICBase::Contextual::decode(extra_state) |
545 ? CALL_AS_FUNCTION | 545 ? CALL_AS_FUNCTION |
546 : CALL_AS_METHOD; | 546 : CALL_AS_METHOD; |
547 ParameterCount actual(argc); | 547 ParameterCount actual(argc); |
548 __ InvokeFunction(r1, | 548 __ InvokeFunction(r1, |
549 actual, | 549 actual, |
550 JUMP_FUNCTION, | 550 JUMP_FUNCTION, |
551 NullCallWrapper(), | 551 NullCallWrapper(), |
552 call_kind); | 552 call_kind); |
553 } | 553 } |
554 | 554 |
555 | 555 |
556 void CallIC::GenerateMiss(MacroAssembler* masm, | |
557 int argc, | |
558 Code::ExtraICState extra_ic_state) { | |
559 // ----------- S t a t e ------------- | |
560 // -- r2 : name | |
561 // -- lr : return address | |
562 // ----------------------------------- | |
563 | |
564 GenerateCallMiss(masm, argc, IC::kCallIC_Miss, extra_ic_state); | |
565 } | |
566 | |
567 | |
568 void CallIC::GenerateMegamorphic(MacroAssembler* masm, | 556 void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
569 int argc, | 557 int argc, |
570 Code::ExtraICState extra_ic_state) { | 558 Code::ExtraICState extra_ic_state) { |
571 // ----------- S t a t e ------------- | 559 // ----------- S t a t e ------------- |
572 // -- r2 : name | 560 // -- r2 : name |
573 // -- lr : return address | 561 // -- lr : return address |
574 // ----------------------------------- | 562 // ----------------------------------- |
575 | 563 |
576 // Get the receiver of the function from the stack into r1. | 564 // Get the receiver of the function from the stack into r1. |
577 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 565 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
578 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); | 566 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); |
579 GenerateMiss(masm, argc, extra_ic_state); | 567 GenerateMiss(masm, argc, extra_ic_state); |
580 } | 568 } |
581 | 569 |
582 | 570 |
583 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { | |
584 // ----------- S t a t e ------------- | |
585 // -- r2 : name | |
586 // -- lr : return address | |
587 // ----------------------------------- | |
588 | |
589 GenerateCallNormal(masm, argc); | |
590 GenerateMiss(masm, argc, Code::kNoExtraICState); | |
591 } | |
592 | |
593 | |
594 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { | |
595 // ----------- S t a t e ------------- | |
596 // -- r2 : name | |
597 // -- lr : return address | |
598 // ----------------------------------- | |
599 | |
600 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss, Code::kNoExtraICState); | |
601 } | |
602 | |
603 | |
604 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 571 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { |
605 // ----------- S t a t e ------------- | 572 // ----------- S t a t e ------------- |
606 // -- r2 : name | 573 // -- r2 : name |
607 // -- lr : return address | 574 // -- lr : return address |
608 // ----------------------------------- | 575 // ----------------------------------- |
609 | 576 |
610 // Get the receiver of the function from the stack into r1. | 577 // Get the receiver of the function from the stack into r1. |
611 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 578 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
612 | 579 |
613 Label do_call, slow_call, slow_load, slow_reload_receiver; | 580 Label do_call, slow_call, slow_load, slow_reload_receiver; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 // ----------- S t a t e ------------- | 678 // ----------- S t a t e ------------- |
712 // -- r2 : name | 679 // -- r2 : name |
713 // -- lr : return address | 680 // -- lr : return address |
714 // ----------------------------------- | 681 // ----------------------------------- |
715 | 682 |
716 // Check if the name is a string. | 683 // Check if the name is a string. |
717 Label miss; | 684 Label miss; |
718 __ JumpIfSmi(r2, &miss); | 685 __ JumpIfSmi(r2, &miss); |
719 __ IsObjectJSStringType(r2, r0, &miss); | 686 __ IsObjectJSStringType(r2, r0, &miss); |
720 | 687 |
721 GenerateCallNormal(masm, argc); | 688 CallICBase::GenerateNormal(masm, argc); |
722 __ bind(&miss); | 689 __ bind(&miss); |
723 GenerateMiss(masm, argc); | 690 GenerateMiss(masm, argc); |
724 } | 691 } |
725 | 692 |
726 | 693 |
727 // Defined in ic.cc. | 694 // Defined in ic.cc. |
728 Object* LoadIC_Miss(Arguments args); | 695 Object* LoadIC_Miss(Arguments args); |
729 | 696 |
730 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 697 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
731 // ----------- S t a t e ------------- | 698 // ----------- S t a t e ------------- |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 __ Push(r2, r1, r0); | 1204 __ Push(r2, r1, r0); |
1238 | 1205 |
1239 // The slow case calls into the runtime to complete the store without causing | 1206 // The slow case calls into the runtime to complete the store without causing |
1240 // an IC miss that would otherwise cause a transition to the generic stub. | 1207 // an IC miss that would otherwise cause a transition to the generic stub. |
1241 ExternalReference ref = | 1208 ExternalReference ref = |
1242 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); | 1209 ExternalReference(IC_Utility(kKeyedStoreIC_Slow), masm->isolate()); |
1243 __ TailCallExternalReference(ref, 3, 1); | 1210 __ TailCallExternalReference(ref, 3, 1); |
1244 } | 1211 } |
1245 | 1212 |
1246 | 1213 |
| 1214 void KeyedStoreIC::GenerateTransitionElementsSmiToDouble(MacroAssembler* masm) { |
| 1215 // ---------- S t a t e -------------- |
| 1216 // -- r2 : receiver |
| 1217 // -- r3 : target map |
| 1218 // -- lr : return address |
| 1219 // ----------------------------------- |
| 1220 // Must return the modified receiver in r0. |
| 1221 if (!FLAG_trace_elements_transitions) { |
| 1222 Label fail; |
| 1223 ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &fail); |
| 1224 __ mov(r0, r2); |
| 1225 __ Ret(); |
| 1226 __ bind(&fail); |
| 1227 } |
| 1228 |
| 1229 __ push(r2); |
| 1230 __ TailCallRuntime(Runtime::kTransitionElementsSmiToDouble, 1, 1); |
| 1231 } |
| 1232 |
| 1233 |
| 1234 void KeyedStoreIC::GenerateTransitionElementsDoubleToObject( |
| 1235 MacroAssembler* masm) { |
| 1236 // ---------- S t a t e -------------- |
| 1237 // -- r2 : receiver |
| 1238 // -- r3 : target map |
| 1239 // -- lr : return address |
| 1240 // ----------------------------------- |
| 1241 // Must return the modified receiver in r0. |
| 1242 if (!FLAG_trace_elements_transitions) { |
| 1243 Label fail; |
| 1244 ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail); |
| 1245 __ mov(r0, r2); |
| 1246 __ Ret(); |
| 1247 __ bind(&fail); |
| 1248 } |
| 1249 |
| 1250 __ push(r2); |
| 1251 __ TailCallRuntime(Runtime::kTransitionElementsDoubleToObject, 1, 1); |
| 1252 } |
| 1253 |
| 1254 |
1247 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1255 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
1248 StrictModeFlag strict_mode) { | 1256 StrictModeFlag strict_mode) { |
1249 // ---------- S t a t e -------------- | 1257 // ---------- S t a t e -------------- |
1250 // -- r0 : value | 1258 // -- r0 : value |
1251 // -- r1 : key | 1259 // -- r1 : key |
1252 // -- r2 : receiver | 1260 // -- r2 : receiver |
1253 // -- lr : return address | 1261 // -- lr : return address |
1254 // ----------------------------------- | 1262 // ----------------------------------- |
1255 | 1263 |
1256 // Push receiver, key and value for runtime call. | 1264 // Push receiver, key and value for runtime call. |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 | 1560 |
1553 | 1561 |
1554 Condition CompareIC::ComputeCondition(Token::Value op) { | 1562 Condition CompareIC::ComputeCondition(Token::Value op) { |
1555 switch (op) { | 1563 switch (op) { |
1556 case Token::EQ_STRICT: | 1564 case Token::EQ_STRICT: |
1557 case Token::EQ: | 1565 case Token::EQ: |
1558 return eq; | 1566 return eq; |
1559 case Token::LT: | 1567 case Token::LT: |
1560 return lt; | 1568 return lt; |
1561 case Token::GT: | 1569 case Token::GT: |
1562 // Reverse left and right operands to obtain ECMA-262 conversion order. | 1570 return gt; |
1563 return lt; | |
1564 case Token::LTE: | 1571 case Token::LTE: |
1565 // Reverse left and right operands to obtain ECMA-262 conversion order. | 1572 return le; |
1566 return ge; | |
1567 case Token::GTE: | 1573 case Token::GTE: |
1568 return ge; | 1574 return ge; |
1569 default: | 1575 default: |
1570 UNREACHABLE(); | 1576 UNREACHABLE(); |
1571 return kNoCondition; | 1577 return kNoCondition; |
1572 } | 1578 } |
1573 } | 1579 } |
1574 | 1580 |
1575 | 1581 |
1576 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { | 1582 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 Register reg = Assembler::GetRn(instr_at_patch); | 1672 Register reg = Assembler::GetRn(instr_at_patch); |
1667 patcher.masm()->tst(reg, Operand(kSmiTagMask)); | 1673 patcher.masm()->tst(reg, Operand(kSmiTagMask)); |
1668 patcher.EmitCondition(eq); | 1674 patcher.EmitCondition(eq); |
1669 } | 1675 } |
1670 } | 1676 } |
1671 | 1677 |
1672 | 1678 |
1673 } } // namespace v8::internal | 1679 } } // namespace v8::internal |
1674 | 1680 |
1675 #endif // V8_TARGET_ARCH_ARM | 1681 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |