| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/ic/call-optimization.h" | 9 #include "src/ic/call-optimization.h" | 
| 10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 85     // We have to return the passed value, not the return value of the setter. | 85     // We have to return the passed value, not the return value of the setter. | 
| 86     __ pop(r0); | 86     __ pop(r0); | 
| 87 | 87 | 
| 88     // Restore context register. | 88     // Restore context register. | 
| 89     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 89     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 
| 90   } | 90   } | 
| 91   __ Ret(); | 91   __ Ret(); | 
| 92 } | 92 } | 
| 93 | 93 | 
| 94 | 94 | 
|  | 95 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector, | 
|  | 96                                                 Register slot) { | 
|  | 97   MacroAssembler* masm = this->masm(); | 
|  | 98   __ push(vector); | 
|  | 99   __ push(slot); | 
|  | 100 } | 
|  | 101 | 
|  | 102 | 
|  | 103 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { | 
|  | 104   MacroAssembler* masm = this->masm(); | 
|  | 105   __ pop(slot); | 
|  | 106   __ pop(vector); | 
|  | 107 } | 
|  | 108 | 
|  | 109 | 
|  | 110 void PropertyHandlerCompiler::DiscardVectorAndSlot() { | 
|  | 111   MacroAssembler* masm = this->masm(); | 
|  | 112   // Remove vector and slot. | 
|  | 113   __ add(sp, sp, Operand(2 * kPointerSize)); | 
|  | 114 } | 
|  | 115 | 
|  | 116 | 
| 95 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 117 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 
| 96     MacroAssembler* masm, Label* miss_label, Register receiver, | 118     MacroAssembler* masm, Label* miss_label, Register receiver, | 
| 97     Handle<Name> name, Register scratch0, Register scratch1) { | 119     Handle<Name> name, Register scratch0, Register scratch1) { | 
| 98   DCHECK(name->IsUniqueName()); | 120   DCHECK(name->IsUniqueName()); | 
| 99   DCHECK(!receiver.is(scratch0)); | 121   DCHECK(!receiver.is(scratch0)); | 
| 100   Counters* counters = masm->isolate()->counters(); | 122   Counters* counters = masm->isolate()->counters(); | 
| 101   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 123   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 
| 102   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 124   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 
| 103 | 125 | 
| 104   Label done; | 126   Label done; | 
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 477   // Return the register containing the holder. | 499   // Return the register containing the holder. | 
| 478   return reg; | 500   return reg; | 
| 479 } | 501 } | 
| 480 | 502 | 
| 481 | 503 | 
| 482 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 504 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 483   if (!miss->is_unused()) { | 505   if (!miss->is_unused()) { | 
| 484     Label success; | 506     Label success; | 
| 485     __ b(&success); | 507     __ b(&success); | 
| 486     __ bind(miss); | 508     __ bind(miss); | 
|  | 509     if (IC::ICUseVector(kind())) { | 
|  | 510       DCHECK(kind() == Code::LOAD_IC); | 
|  | 511       PopVectorAndSlot(); | 
|  | 512     } | 
| 487     TailCallBuiltin(masm(), MissBuiltin(kind())); | 513     TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 488     __ bind(&success); | 514     __ bind(&success); | 
| 489   } | 515   } | 
| 490 } | 516 } | 
| 491 | 517 | 
| 492 | 518 | 
| 493 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 519 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 494   if (!miss->is_unused()) { | 520   if (!miss->is_unused()) { | 
| 495     Label success; | 521     Label success; | 
| 496     __ b(&success); | 522     __ b(&success); | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 575 | 601 | 
| 576   // Save necessary data before invoking an interceptor. | 602   // Save necessary data before invoking an interceptor. | 
| 577   // Requires a frame to make GC aware of pushed pointers. | 603   // Requires a frame to make GC aware of pushed pointers. | 
| 578   { | 604   { | 
| 579     FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); | 605     FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); | 
| 580     if (must_preserve_receiver_reg) { | 606     if (must_preserve_receiver_reg) { | 
| 581       __ Push(receiver(), holder_reg, this->name()); | 607       __ Push(receiver(), holder_reg, this->name()); | 
| 582     } else { | 608     } else { | 
| 583       __ Push(holder_reg, this->name()); | 609       __ Push(holder_reg, this->name()); | 
| 584     } | 610     } | 
|  | 611     InterceptorVectorSlotPush(holder_reg); | 
| 585     // Invoke an interceptor.  Note: map checks from receiver to | 612     // Invoke an interceptor.  Note: map checks from receiver to | 
| 586     // interceptor's holder has been compiled before (see a caller | 613     // interceptor's holder has been compiled before (see a caller | 
| 587     // of this method.) | 614     // of this method.) | 
| 588     CompileCallLoadPropertyWithInterceptor( | 615     CompileCallLoadPropertyWithInterceptor( | 
| 589         masm(), receiver(), holder_reg, this->name(), holder(), | 616         masm(), receiver(), holder_reg, this->name(), holder(), | 
| 590         IC::kLoadPropertyWithInterceptorOnly); | 617         IC::kLoadPropertyWithInterceptorOnly); | 
| 591 | 618 | 
| 592     // Check if interceptor provided a value for property.  If it's | 619     // Check if interceptor provided a value for property.  If it's | 
| 593     // the case, return immediately. | 620     // the case, return immediately. | 
| 594     Label interceptor_failed; | 621     Label interceptor_failed; | 
| 595     __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); | 622     __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); | 
| 596     __ cmp(r0, scratch1()); | 623     __ cmp(r0, scratch1()); | 
| 597     __ b(eq, &interceptor_failed); | 624     __ b(eq, &interceptor_failed); | 
| 598     frame_scope.GenerateLeaveFrame(); | 625     frame_scope.GenerateLeaveFrame(); | 
| 599     __ Ret(); | 626     __ Ret(); | 
| 600 | 627 | 
| 601     __ bind(&interceptor_failed); | 628     __ bind(&interceptor_failed); | 
|  | 629     InterceptorVectorSlotPop(holder_reg); | 
| 602     __ pop(this->name()); | 630     __ pop(this->name()); | 
| 603     __ pop(holder_reg); | 631     __ pop(holder_reg); | 
| 604     if (must_preserve_receiver_reg) { | 632     if (must_preserve_receiver_reg) { | 
| 605       __ pop(receiver()); | 633       __ pop(receiver()); | 
| 606     } | 634     } | 
| 607     // Leave the internal frame. | 635     // Leave the internal frame. | 
| 608   } | 636   } | 
| 609 | 637 | 
| 610   GenerateLoadPostInterceptor(it, holder_reg); | 638   GenerateLoadPostInterceptor(it, holder_reg); | 
| 611 } | 639 } | 
| 612 | 640 | 
| 613 | 641 | 
| 614 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { | 642 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { | 
| 615   // Call the runtime system to load the interceptor. | 643   // Call the runtime system to load the interceptor. | 
| 616   DCHECK(holder()->HasNamedInterceptor()); | 644   DCHECK(holder()->HasNamedInterceptor()); | 
| 617   DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); | 645   DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); | 
| 618   PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), | 646   PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), | 
| 619                            holder()); | 647                            holder()); | 
| 620 | 648 | 
| 621   ExternalReference ref = ExternalReference( | 649   ExternalReference ref = ExternalReference( | 
| 622       IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 650       IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 
| 623   __ TailCallExternalReference( | 651   __ TailCallExternalReference( | 
| 624       ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); | 652       ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); | 
| 625 } | 653 } | 
| 626 | 654 | 
| 627 | 655 | 
| 628 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 656 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 
| 629     Handle<JSObject> object, Handle<Name> name, | 657     Handle<JSObject> object, Handle<Name> name, | 
| 630     Handle<ExecutableAccessorInfo> callback) { | 658     Handle<ExecutableAccessorInfo> callback) { | 
| 631   Register holder_reg = Frontend(receiver(), name); | 659   Register holder_reg = Frontend(name); | 
| 632 | 660 | 
| 633   __ push(receiver());  // receiver | 661   __ push(receiver());  // receiver | 
| 634   __ push(holder_reg); | 662   __ push(holder_reg); | 
| 635   __ mov(ip, Operand(callback));  // callback info | 663   __ mov(ip, Operand(callback));  // callback info | 
| 636   __ push(ip); | 664   __ push(ip); | 
| 637   __ mov(ip, Operand(name)); | 665   __ mov(ip, Operand(name)); | 
| 638   __ Push(ip, value()); | 666   __ Push(ip, value()); | 
| 639 | 667 | 
| 640   // Do tail-call to the runtime system. | 668   // Do tail-call to the runtime system. | 
| 641   ExternalReference store_callback_property = | 669   ExternalReference store_callback_property = | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 662 | 690 | 
| 663 | 691 | 
| 664 Register NamedStoreHandlerCompiler::value() { | 692 Register NamedStoreHandlerCompiler::value() { | 
| 665   return StoreDescriptor::ValueRegister(); | 693   return StoreDescriptor::ValueRegister(); | 
| 666 } | 694 } | 
| 667 | 695 | 
| 668 | 696 | 
| 669 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 697 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 
| 670     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { | 698     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { | 
| 671   Label miss; | 699   Label miss; | 
|  | 700   if (IC::ICUseVector(kind())) { | 
|  | 701     PushVectorAndSlot(); | 
|  | 702   } | 
| 672   FrontendHeader(receiver(), name, &miss); | 703   FrontendHeader(receiver(), name, &miss); | 
| 673 | 704 | 
| 674   // Get the value from the cell. | 705   // Get the value from the cell. | 
| 675   Register result = StoreDescriptor::ValueRegister(); | 706   Register result = StoreDescriptor::ValueRegister(); | 
| 676   __ mov(result, Operand(cell)); | 707   __ mov(result, Operand(cell)); | 
| 677   __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); | 708   __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); | 
| 678 | 709 | 
| 679   // Check for deleted property if property can actually be deleted. | 710   // Check for deleted property if property can actually be deleted. | 
| 680   if (is_configurable) { | 711   if (is_configurable) { | 
| 681     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 712     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 
| 682     __ cmp(result, ip); | 713     __ cmp(result, ip); | 
| 683     __ b(eq, &miss); | 714     __ b(eq, &miss); | 
| 684   } | 715   } | 
| 685 | 716 | 
| 686   Counters* counters = isolate()->counters(); | 717   Counters* counters = isolate()->counters(); | 
| 687   __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); | 718   __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); | 
|  | 719   if (IC::ICUseVector(kind())) { | 
|  | 720     DiscardVectorAndSlot(); | 
|  | 721   } | 
| 688   __ Ret(); | 722   __ Ret(); | 
| 689 | 723 | 
| 690   FrontendFooter(name, &miss); | 724   FrontendFooter(name, &miss); | 
| 691 | 725 | 
| 692   // Return the generated code. | 726   // Return the generated code. | 
| 693   return GetCode(kind(), Code::NORMAL, name); | 727   return GetCode(kind(), Code::NORMAL, name); | 
| 694 } | 728 } | 
| 695 | 729 | 
| 696 | 730 | 
| 697 #undef __ | 731 #undef __ | 
| 698 } | 732 } | 
| 699 }  // namespace v8::internal | 733 }  // namespace v8::internal | 
| 700 | 734 | 
| 701 #endif  // V8_TARGET_ARCH_ARM | 735 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|