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

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

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

Powered by Google App Engine
This is Rietveld 408576698