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

Side by Side Diff: src/ia32/stub-cache-ia32.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/arm64/stub-cache-arm64.cc ('k') | src/ic.cc » ('j') | 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_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 410 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
411 GenerateDictionaryNegativeLookup( 411 GenerateDictionaryNegativeLookup(
412 masm, miss, holder_reg, name, scratch1(), scratch2()); 412 masm, miss, holder_reg, name, scratch1(), scratch2());
413 } 413 }
414 } 414 }
415 415
416 416
417 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 417 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
418 // store is successful. 418 // store is successful.
419 void NamedStoreHandlerCompiler::GenerateStoreTransition( 419 void NamedStoreHandlerCompiler::GenerateStoreTransition(
420 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 420 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition,
421 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 421 Handle<Name> name, Register receiver_reg, Register storage_reg,
422 Register storage_reg, Register value_reg, Register scratch1, 422 Register value_reg, Register scratch1, Register scratch2, Register unused,
423 Register scratch2, Register unused, Label* miss_label, Label* slow) { 423 Label* miss_label, Label* slow) {
424 int descriptor = transition->LastAdded(); 424 int descriptor = transition->LastAdded();
425 DescriptorArray* descriptors = transition->instance_descriptors(); 425 DescriptorArray* descriptors = transition->instance_descriptors();
426 PropertyDetails details = descriptors->GetDetails(descriptor); 426 PropertyDetails details = descriptors->GetDetails(descriptor);
427 Representation representation = details.representation(); 427 Representation representation = details.representation();
428 ASSERT(!representation.IsNone()); 428 ASSERT(!representation.IsNone());
429 429
430 if (details.type() == CONSTANT) { 430 if (details.type() == CONSTANT) {
431 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 431 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
432 __ CmpObject(value_reg, constant); 432 __ CmpObject(value_reg, constant);
433 __ j(not_equal, miss_label); 433 __ j(not_equal, miss_label);
(...skipping 28 matching lines...) Expand all
462 462
463 __ bind(&heap_number); 463 __ bind(&heap_number);
464 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 464 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
465 miss_label, DONT_DO_SMI_CHECK); 465 miss_label, DONT_DO_SMI_CHECK);
466 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 466 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
467 467
468 __ bind(&do_store); 468 __ bind(&do_store);
469 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 469 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
470 } 470 }
471 471
472 // Stub never generated for non-global objects that require access 472 // Stub never generated for objects that require access checks.
473 // checks. 473 ASSERT(!transition->is_access_check_needed());
474 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
475 474
476 // Perform map transition for the receiver if necessary. 475 // Perform map transition for the receiver if necessary.
477 if (details.type() == FIELD && 476 if (details.type() == FIELD &&
478 object->map()->unused_property_fields() == 0) { 477 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
479 // The properties must be extended before we can store the value. 478 // The properties must be extended before we can store the value.
480 // We jump to a runtime call that extends the properties array. 479 // We jump to a runtime call that extends the properties array.
481 __ pop(scratch1); // Return address. 480 __ pop(scratch1); // Return address.
482 __ push(receiver_reg); 481 __ push(receiver_reg);
483 __ push(Immediate(transition)); 482 __ push(Immediate(transition));
484 __ push(value_reg); 483 __ push(value_reg);
485 __ push(scratch1); 484 __ push(scratch1);
486 __ TailCallExternalReference( 485 __ TailCallExternalReference(
487 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 486 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
488 masm->isolate()), 487 masm->isolate()),
(...skipping 20 matching lines...) Expand all
509 __ ret(0); 508 __ ret(0);
510 return; 509 return;
511 } 510 }
512 511
513 int index = transition->instance_descriptors()->GetFieldIndex( 512 int index = transition->instance_descriptors()->GetFieldIndex(
514 transition->LastAdded()); 513 transition->LastAdded());
515 514
516 // Adjust for the number of properties stored in the object. Even in the 515 // Adjust for the number of properties stored in the object. Even in the
517 // face of a transition we can use the old map here because the size of the 516 // face of a transition we can use the old map here because the size of the
518 // object and the number of in-object properties is not going to change. 517 // object and the number of in-object properties is not going to change.
519 index -= object->map()->inobject_properties(); 518 index -= transition->inobject_properties();
520 519
521 SmiCheck smi_check = representation.IsTagged() 520 SmiCheck smi_check = representation.IsTagged()
522 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 521 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
523 // TODO(verwaest): Share this code as a code stub. 522 // TODO(verwaest): Share this code as a code stub.
524 if (index < 0) { 523 if (index < 0) {
525 // Set the property straight into the object. 524 // Set the property straight into the object.
526 int offset = object->map()->instance_size() + (index * kPointerSize); 525 int offset = transition->instance_size() + (index * kPointerSize);
527 if (representation.IsDouble()) { 526 if (representation.IsDouble()) {
528 __ mov(FieldOperand(receiver_reg, offset), storage_reg); 527 __ mov(FieldOperand(receiver_reg, offset), storage_reg);
529 } else { 528 } else {
530 __ mov(FieldOperand(receiver_reg, offset), value_reg); 529 __ mov(FieldOperand(receiver_reg, offset), value_reg);
531 } 530 }
532 531
533 if (!representation.IsSmi()) { 532 if (!representation.IsSmi()) {
534 // Update the write barrier for the array address. 533 // Update the write barrier for the array address.
535 if (!representation.IsDouble()) { 534 if (!representation.IsDouble()) {
536 __ mov(storage_reg, value_reg); 535 __ mov(storage_reg, value_reg);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 Handle<Code> code) { 685 Handle<Code> code) {
687 __ jmp(code, RelocInfo::CODE_TARGET); 686 __ jmp(code, RelocInfo::CODE_TARGET);
688 } 687 }
689 688
690 689
691 #undef __ 690 #undef __
692 #define __ ACCESS_MASM(masm()) 691 #define __ ACCESS_MASM(masm())
693 692
694 693
695 Register PropertyHandlerCompiler::CheckPrototypes( 694 Register PropertyHandlerCompiler::CheckPrototypes(
696 Register object_reg, Handle<JSObject> holder, Register holder_reg, 695 Register object_reg, Register holder_reg, Register scratch1,
697 Register scratch1, Register scratch2, Handle<Name> name, Label* miss, 696 Register scratch2, Handle<Name> name, Label* miss,
698 PrototypeCheckType check) { 697 PrototypeCheckType check) {
699 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 698 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
700 699
701 // Make sure there's no overlap between holder and object registers. 700 // Make sure there's no overlap between holder and object registers.
702 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 701 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
703 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 702 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
704 && !scratch2.is(scratch1)); 703 && !scratch2.is(scratch1));
705 704
706 // Keep track of the current object in register reg. 705 // Keep track of the current object in register reg.
707 Register reg = object_reg; 706 Register reg = object_reg;
708 int depth = 0; 707 int depth = 0;
709 708
710 Handle<JSObject> current = Handle<JSObject>::null(); 709 Handle<JSObject> current = Handle<JSObject>::null();
711 if (type()->IsConstant()) 710 if (type()->IsConstant())
712 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 711 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
713 Handle<JSObject> prototype = Handle<JSObject>::null(); 712 Handle<JSObject> prototype = Handle<JSObject>::null();
714 Handle<Map> current_map = receiver_map; 713 Handle<Map> current_map = receiver_map;
715 Handle<Map> holder_map(holder->map()); 714 Handle<Map> holder_map(holder()->map());
716 // Traverse the prototype chain and check the maps in the prototype chain for 715 // Traverse the prototype chain and check the maps in the prototype chain for
717 // fast and global objects or do negative lookup for normal objects. 716 // fast and global objects or do negative lookup for normal objects.
718 while (!current_map.is_identical_to(holder_map)) { 717 while (!current_map.is_identical_to(holder_map)) {
719 ++depth; 718 ++depth;
720 719
721 // Only global objects and objects that do not require access 720 // Only global objects and objects that do not require access
722 // checks are allowed in stubs. 721 // checks are allowed in stubs.
723 ASSERT(current_map->IsJSGlobalProxyMap() || 722 ASSERT(current_map->IsJSGlobalProxyMap() ||
724 !current_map->is_access_check_needed()); 723 !current_map->is_access_check_needed());
725 724
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 Label success; 817 Label success;
819 __ jmp(&success); 818 __ jmp(&success);
820 GenerateRestoreName(masm(), miss, name); 819 GenerateRestoreName(masm(), miss, name);
821 TailCallBuiltin(masm(), MissBuiltin(kind())); 820 TailCallBuiltin(masm(), MissBuiltin(kind()));
822 __ bind(&success); 821 __ bind(&success);
823 } 822 }
824 } 823 }
825 824
826 825
827 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 826 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
828 Handle<JSObject> holder,
829 Handle<Name> name, 827 Handle<Name> name,
830 Handle<Object> callback) { 828 Handle<Object> callback) {
831 Label miss; 829 Label miss;
832 830
833 Register reg = FrontendHeader(object_reg, holder, name, &miss); 831 Register reg = FrontendHeader(object_reg, name, &miss);
834 832
835 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 833 if (!holder()->HasFastProperties()) {
834 ASSERT(!holder()->IsGlobalObject());
836 ASSERT(!reg.is(scratch2())); 835 ASSERT(!reg.is(scratch2()));
837 ASSERT(!reg.is(scratch3())); 836 ASSERT(!reg.is(scratch3()));
838 Register dictionary = scratch1(); 837 Register dictionary = scratch1();
839 bool must_preserve_dictionary_reg = reg.is(dictionary); 838 bool must_preserve_dictionary_reg = reg.is(dictionary);
840 839
841 // Load the properties dictionary. 840 // Load the properties dictionary.
842 if (must_preserve_dictionary_reg) { 841 if (must_preserve_dictionary_reg) {
843 __ push(dictionary); 842 __ push(dictionary);
844 } 843 }
845 __ mov(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); 844 __ mov(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset));
(...skipping 29 matching lines...) Expand all
875 __ cmp(scratch3(), callback); 874 __ cmp(scratch3(), callback);
876 __ j(not_equal, &miss); 875 __ j(not_equal, &miss);
877 } 876 }
878 877
879 FrontendFooter(name, &miss); 878 FrontendFooter(name, &miss);
880 return reg; 879 return reg;
881 } 880 }
882 881
883 882
884 void NamedLoadHandlerCompiler::GenerateLoadField( 883 void NamedLoadHandlerCompiler::GenerateLoadField(
885 Register reg, Handle<JSObject> holder, FieldIndex field, 884 Register reg, FieldIndex field, Representation representation) {
886 Representation representation) {
887 if (!reg.is(receiver())) __ mov(receiver(), reg); 885 if (!reg.is(receiver())) __ mov(receiver(), reg);
888 LoadFieldStub stub(isolate(), field); 886 LoadFieldStub stub(isolate(), field);
889 GenerateTailCall(masm(), stub.GetCode()); 887 GenerateTailCall(masm(), stub.GetCode());
890 } 888 }
891 889
892 890
893 void NamedLoadHandlerCompiler::GenerateLoadCallback( 891 void NamedLoadHandlerCompiler::GenerateLoadCallback(
894 Register reg, Handle<ExecutableAccessorInfo> callback) { 892 Register reg, Handle<ExecutableAccessorInfo> callback) {
895 // Insert additional parameters into the stack frame above return address. 893 // Insert additional parameters into the stack frame above return address.
896 ASSERT(!scratch3().is(reg)); 894 ASSERT(!scratch3().is(reg));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 } 933 }
936 934
937 935
938 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 936 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
939 // Return the constant value. 937 // Return the constant value.
940 __ LoadObject(eax, value); 938 __ LoadObject(eax, value);
941 __ ret(0); 939 __ ret(0);
942 } 940 }
943 941
944 942
945 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 943 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
946 Register holder_reg, Handle<JSObject> interceptor_holder, 944 LookupResult* lookup,
947 LookupResult* lookup, Handle<Name> name) { 945 Handle<Name> name) {
948 ASSERT(interceptor_holder->HasNamedInterceptor()); 946 ASSERT(holder()->HasNamedInterceptor());
949 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 947 ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
950 948
951 // So far the most popular follow ups for interceptor loads are FIELD 949 // So far the most popular follow ups for interceptor loads are FIELD
952 // and CALLBACKS, so inline only them, other cases may be added 950 // and CALLBACKS, so inline only them, other cases may be added
953 // later. 951 // later.
954 bool compile_followup_inline = false; 952 bool compile_followup_inline = false;
955 if (lookup->IsFound() && lookup->IsCacheable()) { 953 if (lookup->IsFound() && lookup->IsCacheable()) {
956 if (lookup->IsField()) { 954 if (lookup->IsField()) {
957 compile_followup_inline = true; 955 compile_followup_inline = true;
958 } else if (lookup->type() == CALLBACKS && 956 } else if (lookup->type() == CALLBACKS &&
959 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 957 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
960 Handle<ExecutableAccessorInfo> callback( 958 Handle<ExecutableAccessorInfo> callback(
961 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 959 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
962 compile_followup_inline = 960 compile_followup_inline =
963 callback->getter() != NULL && 961 callback->getter() != NULL &&
964 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 962 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
965 type()); 963 type());
966 } 964 }
967 } 965 }
968 966
969 if (compile_followup_inline) { 967 if (compile_followup_inline) {
970 // Compile the interceptor call, followed by inline code to load the 968 // Compile the interceptor call, followed by inline code to load the
971 // property from further up the prototype chain if the call fails. 969 // property from further up the prototype chain if the call fails.
972 // Check that the maps haven't changed. 970 // Check that the maps haven't changed.
973 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 971 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
974 972
975 // Preserve the receiver register explicitly whenever it is different from 973 // Preserve the receiver register explicitly whenever it is different from
976 // the holder and it is needed should the interceptor return without any 974 // the holder and it is needed should the interceptor return without any
977 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 975 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
978 // the FIELD case might cause a miss during the prototype check. 976 // the FIELD case might cause a miss during the prototype check.
979 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 977 bool must_perfrom_prototype_check = *holder() != lookup->holder();
980 bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 978 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
981 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 979 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
982 980
983 // Save necessary data before invoking an interceptor. 981 // Save necessary data before invoking an interceptor.
984 // Requires a frame to make GC aware of pushed pointers. 982 // Requires a frame to make GC aware of pushed pointers.
985 { 983 {
986 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 984 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
987 985
988 if (must_preserve_receiver_reg) { 986 if (must_preserve_receiver_reg) {
989 __ push(receiver()); 987 __ push(receiver());
990 } 988 }
991 __ push(holder_reg); 989 __ push(holder_reg);
992 __ push(this->name()); 990 __ push(this->name());
993 991
994 // Invoke an interceptor. Note: map checks from receiver to 992 // Invoke an interceptor. Note: map checks from receiver to
995 // interceptor's holder has been compiled before (see a caller 993 // interceptor's holder has been compiled before (see a caller
996 // of this method.) 994 // of this method.)
997 CompileCallLoadPropertyWithInterceptor( 995 CompileCallLoadPropertyWithInterceptor(
998 masm(), receiver(), holder_reg, this->name(), interceptor_holder, 996 masm(), receiver(), holder_reg, this->name(), holder(),
999 IC::kLoadPropertyWithInterceptorOnly); 997 IC::kLoadPropertyWithInterceptorOnly);
1000 998
1001 // Check if interceptor provided a value for property. If it's 999 // Check if interceptor provided a value for property. If it's
1002 // the case, return immediately. 1000 // the case, return immediately.
1003 Label interceptor_failed; 1001 Label interceptor_failed;
1004 __ cmp(eax, factory()->no_interceptor_result_sentinel()); 1002 __ cmp(eax, factory()->no_interceptor_result_sentinel());
1005 __ j(equal, &interceptor_failed); 1003 __ j(equal, &interceptor_failed);
1006 frame_scope.GenerateLeaveFrame(); 1004 frame_scope.GenerateLeaveFrame();
1007 __ ret(0); 1005 __ ret(0);
1008 1006
1009 // Clobber registers when generating debug-code to provoke errors. 1007 // Clobber registers when generating debug-code to provoke errors.
1010 __ bind(&interceptor_failed); 1008 __ bind(&interceptor_failed);
1011 if (FLAG_debug_code) { 1009 if (FLAG_debug_code) {
1012 __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue))); 1010 __ mov(receiver(), Immediate(BitCast<int32_t>(kZapValue)));
1013 __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue))); 1011 __ mov(holder_reg, Immediate(BitCast<int32_t>(kZapValue)));
1014 __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue))); 1012 __ mov(this->name(), Immediate(BitCast<int32_t>(kZapValue)));
1015 } 1013 }
1016 1014
1017 __ pop(this->name()); 1015 __ pop(this->name());
1018 __ pop(holder_reg); 1016 __ pop(holder_reg);
1019 if (must_preserve_receiver_reg) { 1017 if (must_preserve_receiver_reg) {
1020 __ pop(receiver()); 1018 __ pop(receiver());
1021 } 1019 }
1022 1020
1023 // Leave the internal frame. 1021 // Leave the internal frame.
1024 } 1022 }
1025 1023
1026 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 1024 GenerateLoadPostInterceptor(holder_reg, name, lookup);
1027 } else { // !compile_followup_inline 1025 } else { // !compile_followup_inline
1028 // Call the runtime system to load the interceptor. 1026 // Call the runtime system to load the interceptor.
1029 // Check that the maps haven't changed. 1027 // Check that the maps haven't changed.
1030 __ pop(scratch2()); // save old return address 1028 __ pop(scratch2()); // save old return address
1031 PushInterceptorArguments(masm(), receiver(), holder_reg, 1029 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
1032 this->name(), interceptor_holder); 1030 holder());
1033 __ push(scratch2()); // restore old return address 1031 __ push(scratch2()); // restore old return address
1034 1032
1035 ExternalReference ref = 1033 ExternalReference ref =
1036 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), 1034 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
1037 isolate()); 1035 isolate());
1038 __ TailCallExternalReference( 1036 __ TailCallExternalReference(
1039 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 1037 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
1040 } 1038 }
1041 } 1039 }
1042 1040
1043 1041
1044 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 1042 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1045 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 1043 Handle<JSObject> object, Handle<Name> name,
1046 Handle<ExecutableAccessorInfo> callback) { 1044 Handle<ExecutableAccessorInfo> callback) {
1047 Register holder_reg = Frontend(receiver(), holder, name); 1045 Register holder_reg = Frontend(receiver(), name);
1048 1046
1049 __ pop(scratch1()); // remove the return address 1047 __ pop(scratch1()); // remove the return address
1050 __ push(receiver()); 1048 __ push(receiver());
1051 __ push(holder_reg); 1049 __ push(holder_reg);
1052 __ Push(callback); 1050 __ Push(callback);
1053 __ Push(name); 1051 __ Push(name);
1054 __ push(value()); 1052 __ push(value());
1055 __ push(scratch1()); // restore return address 1053 __ push(scratch1()); // restore return address
1056 1054
1057 // Do tail-call to the runtime system. 1055 // Do tail-call to the runtime system.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 } 1105 }
1108 __ ret(0); 1106 __ ret(0);
1109 } 1107 }
1110 1108
1111 1109
1112 #undef __ 1110 #undef __
1113 #define __ ACCESS_MASM(masm()) 1111 #define __ ACCESS_MASM(masm())
1114 1112
1115 1113
1116 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 1114 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1117 Handle<JSObject> object, Handle<Name> name) { 1115 Handle<Name> name) {
1118 __ pop(scratch1()); // remove the return address 1116 __ pop(scratch1()); // remove the return address
1119 __ push(receiver()); 1117 __ push(receiver());
1120 __ push(this->name()); 1118 __ push(this->name());
1121 __ push(value()); 1119 __ push(value());
1122 __ push(scratch1()); // restore return address 1120 __ push(scratch1()); // restore return address
1123 1121
1124 // Do tail-call to the runtime system. 1122 // Do tail-call to the runtime system.
1125 ExternalReference store_ic_property = ExternalReference( 1123 ExternalReference store_ic_property = ExternalReference(
1126 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1124 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1127 __ TailCallExternalReference(store_ic_property, 3, 1); 1125 __ TailCallExternalReference(store_ic_property, 3, 1);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 } 1163 }
1166 __ bind(&miss); 1164 __ bind(&miss);
1167 TailCallBuiltin(masm(), MissBuiltin(kind())); 1165 TailCallBuiltin(masm(), MissBuiltin(kind()));
1168 1166
1169 // Return the generated code. 1167 // Return the generated code.
1170 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 1168 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1171 } 1169 }
1172 1170
1173 1171
1174 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1172 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1175 Handle<JSObject> last, Handle<Name> name) { 1173 Handle<Name> name) {
1176 NonexistentFrontend(last, name); 1174 NonexistentFrontend(name);
1177 1175
1178 // Return undefined if maps of the full prototype chain are still the 1176 // Return undefined if maps of the full prototype chain are still the
1179 // same and no global property with this name contains a value. 1177 // same and no global property with this name contains a value.
1180 __ mov(eax, isolate()->factory()->undefined_value()); 1178 __ mov(eax, isolate()->factory()->undefined_value());
1181 __ ret(0); 1179 __ ret(0);
1182 1180
1183 // Return the generated code. 1181 // Return the generated code.
1184 return GetCode(kind(), Code::FAST, name); 1182 return GetCode(kind(), Code::FAST, name);
1185 } 1183 }
1186 1184
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 } 1247 }
1250 __ ret(0); 1248 __ ret(0);
1251 } 1249 }
1252 1250
1253 1251
1254 #undef __ 1252 #undef __
1255 #define __ ACCESS_MASM(masm()) 1253 #define __ ACCESS_MASM(masm())
1256 1254
1257 1255
1258 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1256 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1259 Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name, 1257 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1260 bool is_dont_delete) {
1261 Label miss; 1258 Label miss;
1262 1259
1263 FrontendHeader(receiver(), global, name, &miss); 1260 FrontendHeader(receiver(), name, &miss);
1264 // Get the value from the cell. 1261 // Get the value from the cell.
1265 Register result = StoreIC::ValueRegister(); 1262 Register result = StoreIC::ValueRegister();
1266 if (masm()->serializer_enabled()) { 1263 if (masm()->serializer_enabled()) {
1267 __ mov(result, Immediate(cell)); 1264 __ mov(result, Immediate(cell));
1268 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); 1265 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
1269 } else { 1266 } else {
1270 __ mov(result, Operand::ForCell(cell)); 1267 __ mov(result, Operand::ForCell(cell));
1271 } 1268 }
1272 1269
1273 // Check for deleted property if property can actually be deleted. 1270 // Check for deleted property if property can actually be deleted.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 // ----------------------------------- 1391 // -----------------------------------
1395 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1392 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1396 } 1393 }
1397 1394
1398 1395
1399 #undef __ 1396 #undef __
1400 1397
1401 } } // namespace v8::internal 1398 } } // namespace v8::internal
1402 1399
1403 #endif // V8_TARGET_ARCH_IA32 1400 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm64/stub-cache-arm64.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698