Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 422023003: Encapsulate the holder in the PropertyHolderCompilers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 367 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
368 GenerateDictionaryNegativeLookup( 368 GenerateDictionaryNegativeLookup(
369 masm, miss, holder_reg, name, scratch1(), scratch2()); 369 masm, miss, holder_reg, name, scratch1(), scratch2());
370 } 370 }
371 } 371 }
372 372
373 373
374 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 374 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
375 // store is successful. 375 // store is successful.
376 void NamedStoreHandlerCompiler::GenerateStoreTransition( 376 void NamedStoreHandlerCompiler::GenerateStoreTransition(
377 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 377 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition,
378 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 378 Handle<Name> name, Register receiver_reg, Register storage_reg,
379 Register storage_reg, Register value_reg, Register scratch1, 379 Register value_reg, Register scratch1, Register scratch2, Register unused,
380 Register scratch2, Register unused, Label* miss_label, Label* slow) { 380 Label* miss_label, Label* slow) {
381 int descriptor = transition->LastAdded(); 381 int descriptor = transition->LastAdded();
382 DescriptorArray* descriptors = transition->instance_descriptors(); 382 DescriptorArray* descriptors = transition->instance_descriptors();
383 PropertyDetails details = descriptors->GetDetails(descriptor); 383 PropertyDetails details = descriptors->GetDetails(descriptor);
384 Representation representation = details.representation(); 384 Representation representation = details.representation();
385 ASSERT(!representation.IsNone()); 385 ASSERT(!representation.IsNone());
386 386
387 if (details.type() == CONSTANT) { 387 if (details.type() == CONSTANT) {
388 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 388 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
389 __ Cmp(value_reg, constant); 389 __ Cmp(value_reg, constant);
390 __ j(not_equal, miss_label); 390 __ j(not_equal, miss_label);
(...skipping 27 matching lines...) Expand all
418 418
419 __ bind(&heap_number); 419 __ bind(&heap_number);
420 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 420 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
421 miss_label, DONT_DO_SMI_CHECK); 421 miss_label, DONT_DO_SMI_CHECK);
422 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 422 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
423 423
424 __ bind(&do_store); 424 __ bind(&do_store);
425 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 425 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
426 } 426 }
427 427
428 // Stub never generated for non-global objects that require access 428 // Stub never generated for objects that require access checks.
429 // checks. 429 ASSERT(!transition->is_access_check_needed());
430 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
431 430
432 // Perform map transition for the receiver if necessary. 431 // Perform map transition for the receiver if necessary.
433 if (details.type() == FIELD && 432 if (details.type() == FIELD &&
434 object->map()->unused_property_fields() == 0) { 433 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
435 // The properties must be extended before we can store the value. 434 // The properties must be extended before we can store the value.
436 // We jump to a runtime call that extends the properties array. 435 // We jump to a runtime call that extends the properties array.
437 __ PopReturnAddressTo(scratch1); 436 __ PopReturnAddressTo(scratch1);
438 __ Push(receiver_reg); 437 __ Push(receiver_reg);
439 __ Push(transition); 438 __ Push(transition);
440 __ Push(value_reg); 439 __ Push(value_reg);
441 __ PushReturnAddressFrom(scratch1); 440 __ PushReturnAddressFrom(scratch1);
442 __ TailCallExternalReference( 441 __ TailCallExternalReference(
443 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 442 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
444 masm->isolate()), 443 masm->isolate()),
(...skipping 20 matching lines...) Expand all
465 __ ret(0); 464 __ ret(0);
466 return; 465 return;
467 } 466 }
468 467
469 int index = transition->instance_descriptors()->GetFieldIndex( 468 int index = transition->instance_descriptors()->GetFieldIndex(
470 transition->LastAdded()); 469 transition->LastAdded());
471 470
472 // Adjust for the number of properties stored in the object. Even in the 471 // Adjust for the number of properties stored in the object. Even in the
473 // face of a transition we can use the old map here because the size of the 472 // face of a transition we can use the old map here because the size of the
474 // object and the number of in-object properties is not going to change. 473 // object and the number of in-object properties is not going to change.
475 index -= object->map()->inobject_properties(); 474 index -= transition->inobject_properties();
476 475
477 // TODO(verwaest): Share this code as a code stub. 476 // TODO(verwaest): Share this code as a code stub.
478 SmiCheck smi_check = representation.IsTagged() 477 SmiCheck smi_check = representation.IsTagged()
479 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 478 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
480 if (index < 0) { 479 if (index < 0) {
481 // Set the property straight into the object. 480 // Set the property straight into the object.
482 int offset = object->map()->instance_size() + (index * kPointerSize); 481 int offset = transition->instance_size() + (index * kPointerSize);
483 if (representation.IsDouble()) { 482 if (representation.IsDouble()) {
484 __ movp(FieldOperand(receiver_reg, offset), storage_reg); 483 __ movp(FieldOperand(receiver_reg, offset), storage_reg);
485 } else { 484 } else {
486 __ movp(FieldOperand(receiver_reg, offset), value_reg); 485 __ movp(FieldOperand(receiver_reg, offset), value_reg);
487 } 486 }
488 487
489 if (!representation.IsSmi()) { 488 if (!representation.IsSmi()) {
490 // Update the write barrier for the array address. 489 // Update the write barrier for the array address.
491 if (!representation.IsDouble()) { 490 if (!representation.IsDouble()) {
492 __ movp(storage_reg, value_reg); 491 __ movp(storage_reg, value_reg);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 Handle<Code> code) { 625 Handle<Code> code) {
627 __ jmp(code, RelocInfo::CODE_TARGET); 626 __ jmp(code, RelocInfo::CODE_TARGET);
628 } 627 }
629 628
630 629
631 #undef __ 630 #undef __
632 #define __ ACCESS_MASM((masm())) 631 #define __ ACCESS_MASM((masm()))
633 632
634 633
635 Register PropertyHandlerCompiler::CheckPrototypes( 634 Register PropertyHandlerCompiler::CheckPrototypes(
636 Register object_reg, Handle<JSObject> holder, Register holder_reg, 635 Register object_reg, Register holder_reg, Register scratch1,
637 Register scratch1, Register scratch2, Handle<Name> name, Label* miss, 636 Register scratch2, Handle<Name> name, Label* miss,
638 PrototypeCheckType check) { 637 PrototypeCheckType check) {
639 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 638 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
640 639
641 // Make sure there's no overlap between holder and object registers. 640 // Make sure there's no overlap between holder and object registers.
642 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 641 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
643 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 642 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
644 && !scratch2.is(scratch1)); 643 && !scratch2.is(scratch1));
645 644
646 // Keep track of the current object in register reg. On the first 645 // Keep track of the current object in register reg. On the first
647 // iteration, reg is an alias for object_reg, on later iterations, 646 // iteration, reg is an alias for object_reg, on later iterations,
648 // it is an alias for holder_reg. 647 // it is an alias for holder_reg.
649 Register reg = object_reg; 648 Register reg = object_reg;
650 int depth = 0; 649 int depth = 0;
651 650
652 Handle<JSObject> current = Handle<JSObject>::null(); 651 Handle<JSObject> current = Handle<JSObject>::null();
653 if (type()->IsConstant()) { 652 if (type()->IsConstant()) {
654 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 653 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
655 } 654 }
656 Handle<JSObject> prototype = Handle<JSObject>::null(); 655 Handle<JSObject> prototype = Handle<JSObject>::null();
657 Handle<Map> current_map = receiver_map; 656 Handle<Map> current_map = receiver_map;
658 Handle<Map> holder_map(holder->map()); 657 Handle<Map> holder_map(holder()->map());
659 // Traverse the prototype chain and check the maps in the prototype chain for 658 // Traverse the prototype chain and check the maps in the prototype chain for
660 // fast and global objects or do negative lookup for normal objects. 659 // fast and global objects or do negative lookup for normal objects.
661 while (!current_map.is_identical_to(holder_map)) { 660 while (!current_map.is_identical_to(holder_map)) {
662 ++depth; 661 ++depth;
663 662
664 // Only global objects and objects that do not require access 663 // Only global objects and objects that do not require access
665 // checks are allowed in stubs. 664 // checks are allowed in stubs.
666 ASSERT(current_map->IsJSGlobalProxyMap() || 665 ASSERT(current_map->IsJSGlobalProxyMap() ||
667 !current_map->is_access_check_needed()); 666 !current_map->is_access_check_needed());
668 667
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 Label success; 758 Label success;
760 __ jmp(&success); 759 __ jmp(&success);
761 GenerateRestoreName(masm(), miss, name); 760 GenerateRestoreName(masm(), miss, name);
762 TailCallBuiltin(masm(), MissBuiltin(kind())); 761 TailCallBuiltin(masm(), MissBuiltin(kind()));
763 __ bind(&success); 762 __ bind(&success);
764 } 763 }
765 } 764 }
766 765
767 766
768 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 767 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
769 Handle<JSObject> holder,
770 Handle<Name> name, 768 Handle<Name> name,
771 Handle<Object> callback) { 769 Handle<Object> callback) {
772 Label miss; 770 Label miss;
773 771
774 Register reg = FrontendHeader(object_reg, holder, name, &miss); 772 Register reg = FrontendHeader(object_reg, name, &miss);
775 773
776 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 774 if (!holder()->HasFastProperties()) {
775 ASSERT(!holder()->IsGlobalObject());
777 ASSERT(!reg.is(scratch2())); 776 ASSERT(!reg.is(scratch2()));
778 ASSERT(!reg.is(scratch3())); 777 ASSERT(!reg.is(scratch3()));
779 ASSERT(!reg.is(scratch4())); 778 ASSERT(!reg.is(scratch4()));
780 779
781 // Load the properties dictionary. 780 // Load the properties dictionary.
782 Register dictionary = scratch4(); 781 Register dictionary = scratch4();
783 __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); 782 __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset));
784 783
785 // Probe the dictionary. 784 // Probe the dictionary.
786 Label probe_done; 785 Label probe_done;
(...skipping 20 matching lines...) Expand all
807 __ cmpp(scratch2(), scratch3()); 806 __ cmpp(scratch2(), scratch3());
808 __ j(not_equal, &miss); 807 __ j(not_equal, &miss);
809 } 808 }
810 809
811 FrontendFooter(name, &miss); 810 FrontendFooter(name, &miss);
812 return reg; 811 return reg;
813 } 812 }
814 813
815 814
816 void NamedLoadHandlerCompiler::GenerateLoadField( 815 void NamedLoadHandlerCompiler::GenerateLoadField(
817 Register reg, Handle<JSObject> holder, FieldIndex field, 816 Register reg, FieldIndex field, Representation representation) {
818 Representation representation) {
819 if (!reg.is(receiver())) __ movp(receiver(), reg); 817 if (!reg.is(receiver())) __ movp(receiver(), reg);
820 LoadFieldStub stub(isolate(), field); 818 LoadFieldStub stub(isolate(), field);
821 GenerateTailCall(masm(), stub.GetCode()); 819 GenerateTailCall(masm(), stub.GetCode());
822 } 820 }
823 821
824 822
825 void NamedLoadHandlerCompiler::GenerateLoadCallback( 823 void NamedLoadHandlerCompiler::GenerateLoadCallback(
826 Register reg, Handle<ExecutableAccessorInfo> callback) { 824 Register reg, Handle<ExecutableAccessorInfo> callback) {
827 // Insert additional parameters into the stack frame above return address. 825 // Insert additional parameters into the stack frame above return address.
828 ASSERT(!scratch4().is(reg)); 826 ASSERT(!scratch4().is(reg));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 } 864 }
867 865
868 866
869 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 867 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
870 // Return the constant value. 868 // Return the constant value.
871 __ Move(rax, value); 869 __ Move(rax, value);
872 __ ret(0); 870 __ ret(0);
873 } 871 }
874 872
875 873
876 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 874 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
877 Register holder_reg, Handle<JSObject> interceptor_holder, 875 LookupResult* lookup,
878 LookupResult* lookup, Handle<Name> name) { 876 Handle<Name> name) {
879 ASSERT(interceptor_holder->HasNamedInterceptor()); 877 ASSERT(holder()->HasNamedInterceptor());
880 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 878 ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
881 879
882 // So far the most popular follow ups for interceptor loads are FIELD 880 // So far the most popular follow ups for interceptor loads are FIELD
883 // and CALLBACKS, so inline only them, other cases may be added 881 // and CALLBACKS, so inline only them, other cases may be added
884 // later. 882 // later.
885 bool compile_followup_inline = false; 883 bool compile_followup_inline = false;
886 if (lookup->IsFound() && lookup->IsCacheable()) { 884 if (lookup->IsFound() && lookup->IsCacheable()) {
887 if (lookup->IsField()) { 885 if (lookup->IsField()) {
888 compile_followup_inline = true; 886 compile_followup_inline = true;
889 } else if (lookup->type() == CALLBACKS && 887 } else if (lookup->type() == CALLBACKS &&
890 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 888 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
891 Handle<ExecutableAccessorInfo> callback( 889 Handle<ExecutableAccessorInfo> callback(
892 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 890 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
893 compile_followup_inline = 891 compile_followup_inline =
894 callback->getter() != NULL && 892 callback->getter() != NULL &&
895 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 893 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
896 type()); 894 type());
897 } 895 }
898 } 896 }
899 897
900 if (compile_followup_inline) { 898 if (compile_followup_inline) {
901 // Compile the interceptor call, followed by inline code to load the 899 // Compile the interceptor call, followed by inline code to load the
902 // property from further up the prototype chain if the call fails. 900 // property from further up the prototype chain if the call fails.
903 // Check that the maps haven't changed. 901 // Check that the maps haven't changed.
904 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 902 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
905 903
906 // Preserve the receiver register explicitly whenever it is different from 904 // Preserve the receiver register explicitly whenever it is different from
907 // the holder and it is needed should the interceptor return without any 905 // the holder and it is needed should the interceptor return without any
908 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 906 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
909 // the FIELD case might cause a miss during the prototype check. 907 // the FIELD case might cause a miss during the prototype check.
910 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 908 bool must_perfrom_prototype_check = *holder() != lookup->holder();
911 bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 909 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
912 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 910 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
913 911
914 // Save necessary data before invoking an interceptor. 912 // Save necessary data before invoking an interceptor.
915 // Requires a frame to make GC aware of pushed pointers. 913 // Requires a frame to make GC aware of pushed pointers.
916 { 914 {
917 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 915 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
918 916
919 if (must_preserve_receiver_reg) { 917 if (must_preserve_receiver_reg) {
920 __ Push(receiver()); 918 __ Push(receiver());
921 } 919 }
922 __ Push(holder_reg); 920 __ Push(holder_reg);
923 __ Push(this->name()); 921 __ Push(this->name());
924 922
925 // Invoke an interceptor. Note: map checks from receiver to 923 // Invoke an interceptor. Note: map checks from receiver to
926 // interceptor's holder has been compiled before (see a caller 924 // interceptor's holder has been compiled before (see a caller
927 // of this method.) 925 // of this method.)
928 CompileCallLoadPropertyWithInterceptor( 926 CompileCallLoadPropertyWithInterceptor(
929 masm(), receiver(), holder_reg, this->name(), interceptor_holder, 927 masm(), receiver(), holder_reg, this->name(), holder(),
930 IC::kLoadPropertyWithInterceptorOnly); 928 IC::kLoadPropertyWithInterceptorOnly);
931 929
932 // Check if interceptor provided a value for property. If it's 930 // Check if interceptor provided a value for property. If it's
933 // the case, return immediately. 931 // the case, return immediately.
934 Label interceptor_failed; 932 Label interceptor_failed;
935 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 933 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
936 __ j(equal, &interceptor_failed); 934 __ j(equal, &interceptor_failed);
937 frame_scope.GenerateLeaveFrame(); 935 frame_scope.GenerateLeaveFrame();
938 __ ret(0); 936 __ ret(0);
939 937
940 __ bind(&interceptor_failed); 938 __ bind(&interceptor_failed);
941 __ Pop(this->name()); 939 __ Pop(this->name());
942 __ Pop(holder_reg); 940 __ Pop(holder_reg);
943 if (must_preserve_receiver_reg) { 941 if (must_preserve_receiver_reg) {
944 __ Pop(receiver()); 942 __ Pop(receiver());
945 } 943 }
946 944
947 // Leave the internal frame. 945 // Leave the internal frame.
948 } 946 }
949 947
950 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 948 GenerateLoadPostInterceptor(holder_reg, name, lookup);
951 } else { // !compile_followup_inline 949 } else { // !compile_followup_inline
952 // Call the runtime system to load the interceptor. 950 // Call the runtime system to load the interceptor.
953 // Check that the maps haven't changed. 951 // Check that the maps haven't changed.
954 __ PopReturnAddressTo(scratch2()); 952 __ PopReturnAddressTo(scratch2());
955 PushInterceptorArguments(masm(), receiver(), holder_reg, 953 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
956 this->name(), interceptor_holder); 954 holder());
957 __ PushReturnAddressFrom(scratch2()); 955 __ PushReturnAddressFrom(scratch2());
958 956
959 ExternalReference ref = ExternalReference( 957 ExternalReference ref = ExternalReference(
960 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 958 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
961 __ TailCallExternalReference( 959 __ TailCallExternalReference(
962 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 960 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
963 } 961 }
964 } 962 }
965 963
966 964
967 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 965 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
968 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 966 Handle<JSObject> object, Handle<Name> name,
969 Handle<ExecutableAccessorInfo> callback) { 967 Handle<ExecutableAccessorInfo> callback) {
970 Register holder_reg = Frontend(receiver(), holder, name); 968 Register holder_reg = Frontend(receiver(), name);
971 969
972 __ PopReturnAddressTo(scratch1()); 970 __ PopReturnAddressTo(scratch1());
973 __ Push(receiver()); 971 __ Push(receiver());
974 __ Push(holder_reg); 972 __ Push(holder_reg);
975 __ Push(callback); // callback info 973 __ Push(callback); // callback info
976 __ Push(name); 974 __ Push(name);
977 __ Push(value()); 975 __ Push(value());
978 __ PushReturnAddressFrom(scratch1()); 976 __ PushReturnAddressFrom(scratch1());
979 977
980 // Do tail-call to the runtime system. 978 // Do tail-call to the runtime system.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 } 1028 }
1031 __ ret(0); 1029 __ ret(0);
1032 } 1030 }
1033 1031
1034 1032
1035 #undef __ 1033 #undef __
1036 #define __ ACCESS_MASM(masm()) 1034 #define __ ACCESS_MASM(masm())
1037 1035
1038 1036
1039 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 1037 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1040 Handle<JSObject> object, Handle<Name> name) { 1038 Handle<Name> name) {
1041 __ PopReturnAddressTo(scratch1()); 1039 __ PopReturnAddressTo(scratch1());
1042 __ Push(receiver()); 1040 __ Push(receiver());
1043 __ Push(this->name()); 1041 __ Push(this->name());
1044 __ Push(value()); 1042 __ Push(value());
1045 __ PushReturnAddressFrom(scratch1()); 1043 __ PushReturnAddressFrom(scratch1());
1046 1044
1047 // Do tail-call to the runtime system. 1045 // Do tail-call to the runtime system.
1048 ExternalReference store_ic_property = ExternalReference( 1046 ExternalReference store_ic_property = ExternalReference(
1049 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1047 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1050 __ TailCallExternalReference(store_ic_property, 3, 1); 1048 __ TailCallExternalReference(store_ic_property, 3, 1);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 __ bind(&miss); 1093 __ bind(&miss);
1096 1094
1097 TailCallBuiltin(masm(), MissBuiltin(kind())); 1095 TailCallBuiltin(masm(), MissBuiltin(kind()));
1098 1096
1099 // Return the generated code. 1097 // Return the generated code.
1100 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 1098 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1101 } 1099 }
1102 1100
1103 1101
1104 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1102 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1105 Handle<JSObject> last, Handle<Name> name) { 1103 Handle<Name> name) {
1106 NonexistentFrontend(last, name); 1104 NonexistentFrontend(name);
1107 1105
1108 // Return undefined if maps of the full prototype chain are still the 1106 // Return undefined if maps of the full prototype chain are still the
1109 // same and no global property with this name contains a value. 1107 // same and no global property with this name contains a value.
1110 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1108 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1111 __ ret(0); 1109 __ ret(0);
1112 1110
1113 // Return the generated code. 1111 // Return the generated code.
1114 return GetCode(kind(), Code::FAST, name); 1112 return GetCode(kind(), Code::FAST, name);
1115 } 1113 }
1116 1114
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 } 1182 }
1185 __ ret(0); 1183 __ ret(0);
1186 } 1184 }
1187 1185
1188 1186
1189 #undef __ 1187 #undef __
1190 #define __ ACCESS_MASM(masm()) 1188 #define __ ACCESS_MASM(masm())
1191 1189
1192 1190
1193 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1191 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1194 Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name, 1192 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1195 bool is_dont_delete) {
1196 Label miss; 1193 Label miss;
1197 FrontendHeader(receiver(), global, name, &miss); 1194 FrontendHeader(receiver(), name, &miss);
1198 1195
1199 // Get the value from the cell. 1196 // Get the value from the cell.
1200 Register result = StoreIC::ValueRegister(); 1197 Register result = StoreIC::ValueRegister();
1201 __ Move(result, cell); 1198 __ Move(result, cell);
1202 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); 1199 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
1203 1200
1204 // Check for deleted property if property can actually be deleted. 1201 // Check for deleted property if property can actually be deleted.
1205 if (!is_dont_delete) { 1202 if (!is_dont_delete) {
1206 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 1203 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
1207 __ j(equal, &miss); 1204 __ j(equal, &miss);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 // ----------------------------------- 1320 // -----------------------------------
1324 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1321 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1325 } 1322 }
1326 1323
1327 1324
1328 #undef __ 1325 #undef __
1329 1326
1330 } } // namespace v8::internal 1327 } } // namespace v8::internal
1331 1328
1332 #endif // V8_TARGET_ARCH_X64 1329 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698