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

Side by Side Diff: src/arm64/stub-cache-arm64.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/arm/stub-cache-arm.cc ('k') | src/ia32/stub-cache-ia32.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 masm, miss, holder_reg, name, scratch1(), scratch2()); 258 masm, miss, holder_reg, name, scratch1(), scratch2());
259 } 259 }
260 } 260 }
261 261
262 262
263 // Generate StoreTransition code, value is passed in x0 register. 263 // Generate StoreTransition code, value is passed in x0 register.
264 // When leaving generated code after success, the receiver_reg and storage_reg 264 // When leaving generated code after success, the receiver_reg and storage_reg
265 // may be clobbered. Upon branch to miss_label, the receiver and name registers 265 // may be clobbered. Upon branch to miss_label, the receiver and name registers
266 // have their original values. 266 // have their original values.
267 void NamedStoreHandlerCompiler::GenerateStoreTransition( 267 void NamedStoreHandlerCompiler::GenerateStoreTransition(
268 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 268 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition,
269 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 269 Handle<Name> name, Register receiver_reg, Register storage_reg,
270 Register storage_reg, Register value_reg, Register scratch1, 270 Register value_reg, Register scratch1, Register scratch2, Register scratch3,
271 Register scratch2, Register scratch3, Label* miss_label, Label* slow) { 271 Label* miss_label, Label* slow) {
272 Label exit; 272 Label exit;
273 273
274 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg, 274 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg,
275 scratch1, scratch2, scratch3)); 275 scratch1, scratch2, scratch3));
276 276
277 // We don't need scratch3. 277 // We don't need scratch3.
278 scratch3 = NoReg; 278 scratch3 = NoReg;
279 279
280 int descriptor = transition->LastAdded(); 280 int descriptor = transition->LastAdded();
281 DescriptorArray* descriptors = transition->instance_descriptors(); 281 DescriptorArray* descriptors = transition->instance_descriptors();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 318
319 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 319 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
320 miss_label, DONT_DO_SMI_CHECK); 320 miss_label, DONT_DO_SMI_CHECK);
321 __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 321 __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
322 322
323 __ Bind(&do_store); 323 __ Bind(&do_store);
324 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double, 324 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double,
325 NoReg, MUTABLE); 325 NoReg, MUTABLE);
326 } 326 }
327 327
328 // Stub never generated for non-global objects that require access checks. 328 // Stub never generated for objects that require access checks.
329 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 329 ASSERT(!transition->is_access_check_needed());
330 330
331 // Perform map transition for the receiver if necessary. 331 // Perform map transition for the receiver if necessary.
332 if ((details.type() == FIELD) && 332 if (details.type() == FIELD &&
333 (object->map()->unused_property_fields() == 0)) { 333 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
334 // The properties must be extended before we can store the value. 334 // The properties must be extended before we can store the value.
335 // We jump to a runtime call that extends the properties array. 335 // We jump to a runtime call that extends the properties array.
336 __ Mov(scratch1, Operand(transition)); 336 __ Mov(scratch1, Operand(transition));
337 __ Push(receiver_reg, scratch1, value_reg); 337 __ Push(receiver_reg, scratch1, value_reg);
338 __ TailCallExternalReference( 338 __ TailCallExternalReference(
339 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 339 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
340 masm->isolate()), 340 masm->isolate()),
341 3, 341 3,
342 1); 342 1);
343 return; 343 return;
(...skipping 18 matching lines...) Expand all
362 __ Ret(); 362 __ Ret();
363 return; 363 return;
364 } 364 }
365 365
366 int index = transition->instance_descriptors()->GetFieldIndex( 366 int index = transition->instance_descriptors()->GetFieldIndex(
367 transition->LastAdded()); 367 transition->LastAdded());
368 368
369 // Adjust for the number of properties stored in the object. Even in the 369 // Adjust for the number of properties stored in the object. Even in the
370 // face of a transition we can use the old map here because the size of the 370 // face of a transition we can use the old map here because the size of the
371 // object and the number of in-object properties is not going to change. 371 // object and the number of in-object properties is not going to change.
372 index -= object->map()->inobject_properties(); 372 index -= transition->inobject_properties();
373 373
374 // TODO(verwaest): Share this code as a code stub. 374 // TODO(verwaest): Share this code as a code stub.
375 SmiCheck smi_check = representation.IsTagged() 375 SmiCheck smi_check = representation.IsTagged()
376 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 376 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
377 Register prop_reg = representation.IsDouble() ? storage_reg : value_reg; 377 Register prop_reg = representation.IsDouble() ? storage_reg : value_reg;
378 if (index < 0) { 378 if (index < 0) {
379 // Set the property straight into the object. 379 // Set the property straight into the object.
380 int offset = object->map()->instance_size() + (index * kPointerSize); 380 int offset = transition->instance_size() + (index * kPointerSize);
381 __ Str(prop_reg, FieldMemOperand(receiver_reg, offset)); 381 __ Str(prop_reg, FieldMemOperand(receiver_reg, offset));
382 382
383 if (!representation.IsSmi()) { 383 if (!representation.IsSmi()) {
384 // Update the write barrier for the array address. 384 // Update the write barrier for the array address.
385 if (!representation.IsDouble()) { 385 if (!representation.IsDouble()) {
386 __ Mov(storage_reg, value_reg); 386 __ Mov(storage_reg, value_reg);
387 } 387 }
388 __ RecordWriteField(receiver_reg, 388 __ RecordWriteField(receiver_reg,
389 offset, 389 offset,
390 storage_reg, 390 storage_reg,
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 Handle<Code> code) { 675 Handle<Code> code) {
676 __ Jump(code, RelocInfo::CODE_TARGET); 676 __ Jump(code, RelocInfo::CODE_TARGET);
677 } 677 }
678 678
679 679
680 #undef __ 680 #undef __
681 #define __ ACCESS_MASM(masm()) 681 #define __ ACCESS_MASM(masm())
682 682
683 683
684 Register PropertyHandlerCompiler::CheckPrototypes( 684 Register PropertyHandlerCompiler::CheckPrototypes(
685 Register object_reg, Handle<JSObject> holder, Register holder_reg, 685 Register object_reg, Register holder_reg, Register scratch1,
686 Register scratch1, Register scratch2, Handle<Name> name, Label* miss, 686 Register scratch2, Handle<Name> name, Label* miss,
687 PrototypeCheckType check) { 687 PrototypeCheckType check) {
688 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 688 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
689 689
690 // object_reg and holder_reg registers can alias. 690 // object_reg and holder_reg registers can alias.
691 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); 691 ASSERT(!AreAliased(object_reg, scratch1, scratch2));
692 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); 692 ASSERT(!AreAliased(holder_reg, scratch1, scratch2));
693 693
694 // Keep track of the current object in register reg. 694 // Keep track of the current object in register reg.
695 Register reg = object_reg; 695 Register reg = object_reg;
696 int depth = 0; 696 int depth = 0;
697 697
698 Handle<JSObject> current = Handle<JSObject>::null(); 698 Handle<JSObject> current = Handle<JSObject>::null();
699 if (type()->IsConstant()) { 699 if (type()->IsConstant()) {
700 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 700 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
701 } 701 }
702 Handle<JSObject> prototype = Handle<JSObject>::null(); 702 Handle<JSObject> prototype = Handle<JSObject>::null();
703 Handle<Map> current_map = receiver_map; 703 Handle<Map> current_map = receiver_map;
704 Handle<Map> holder_map(holder->map()); 704 Handle<Map> holder_map(holder()->map());
705 // Traverse the prototype chain and check the maps in the prototype chain for 705 // Traverse the prototype chain and check the maps in the prototype chain for
706 // fast and global objects or do negative lookup for normal objects. 706 // fast and global objects or do negative lookup for normal objects.
707 while (!current_map.is_identical_to(holder_map)) { 707 while (!current_map.is_identical_to(holder_map)) {
708 ++depth; 708 ++depth;
709 709
710 // Only global objects and objects that do not require access 710 // Only global objects and objects that do not require access
711 // checks are allowed in stubs. 711 // checks are allowed in stubs.
712 ASSERT(current_map->IsJSGlobalProxyMap() || 712 ASSERT(current_map->IsJSGlobalProxyMap() ||
713 !current_map->is_access_check_needed()); 713 !current_map->is_access_check_needed());
714 714
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 811
812 GenerateRestoreName(masm(), miss, name); 812 GenerateRestoreName(masm(), miss, name);
813 TailCallBuiltin(masm(), MissBuiltin(kind())); 813 TailCallBuiltin(masm(), MissBuiltin(kind()));
814 814
815 __ Bind(&success); 815 __ Bind(&success);
816 } 816 }
817 } 817 }
818 818
819 819
820 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 820 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
821 Handle<JSObject> holder,
822 Handle<Name> name, 821 Handle<Name> name,
823 Handle<Object> callback) { 822 Handle<Object> callback) {
824 Label miss; 823 Label miss;
825 824
826 Register reg = FrontendHeader(object_reg, holder, name, &miss); 825 Register reg = FrontendHeader(object_reg, name, &miss);
827 // FrontendHeader can return its result into scratch1() so do not 826 // FrontendHeader can return its result into scratch1() so do not
828 // use it. 827 // use it.
829 Register scratch2 = this->scratch2(); 828 Register scratch2 = this->scratch2();
830 Register scratch3 = this->scratch3(); 829 Register scratch3 = this->scratch3();
831 Register dictionary = this->scratch4(); 830 Register dictionary = this->scratch4();
832 ASSERT(!AreAliased(reg, scratch2, scratch3, dictionary)); 831 ASSERT(!AreAliased(reg, scratch2, scratch3, dictionary));
833 832
834 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 833 if (!holder()->HasFastProperties()) {
834 ASSERT(holder()->IsGlobalObject());
835 // Load the properties dictionary. 835 // Load the properties dictionary.
836 __ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 836 __ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
837 837
838 // Probe the dictionary. 838 // Probe the dictionary.
839 Label probe_done; 839 Label probe_done;
840 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), 840 NameDictionaryLookupStub::GeneratePositiveLookup(masm(),
841 &miss, 841 &miss,
842 &probe_done, 842 &probe_done,
843 dictionary, 843 dictionary,
844 this->name(), 844 this->name(),
(...skipping 11 matching lines...) Expand all
856 __ Cmp(scratch2, Operand(callback)); 856 __ Cmp(scratch2, Operand(callback));
857 __ B(ne, &miss); 857 __ B(ne, &miss);
858 } 858 }
859 859
860 FrontendFooter(name, &miss); 860 FrontendFooter(name, &miss);
861 return reg; 861 return reg;
862 } 862 }
863 863
864 864
865 void NamedLoadHandlerCompiler::GenerateLoadField( 865 void NamedLoadHandlerCompiler::GenerateLoadField(
866 Register reg, Handle<JSObject> holder, FieldIndex field, 866 Register reg, FieldIndex field, Representation representation) {
867 Representation representation) {
868 __ Mov(receiver(), reg); 867 __ Mov(receiver(), reg);
869 LoadFieldStub stub(isolate(), field); 868 LoadFieldStub stub(isolate(), field);
870 GenerateTailCall(masm(), stub.GetCode()); 869 GenerateTailCall(masm(), stub.GetCode());
871 } 870 }
872 871
873 872
874 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 873 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
875 // Return the constant value. 874 // Return the constant value.
876 __ LoadObject(x0, value); 875 __ LoadObject(x0, value);
877 __ Ret(); 876 __ Ret();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 ApiFunction fun(getter_address); 924 ApiFunction fun(getter_address);
926 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 925 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
927 ExternalReference ref = ExternalReference(&fun, type, isolate()); 926 ExternalReference ref = ExternalReference(&fun, type, isolate());
928 __ Mov(getter_address_reg, ref); 927 __ Mov(getter_address_reg, ref);
929 928
930 CallApiGetterStub stub(isolate()); 929 CallApiGetterStub stub(isolate());
931 __ TailCallStub(&stub); 930 __ TailCallStub(&stub);
932 } 931 }
933 932
934 933
935 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 934 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
936 Register holder_reg, Handle<JSObject> interceptor_holder, 935 LookupResult* lookup,
937 LookupResult* lookup, Handle<Name> name) { 936 Handle<Name> name) {
938 ASSERT(!AreAliased(receiver(), this->name(), 937 ASSERT(!AreAliased(receiver(), this->name(),
939 scratch1(), scratch2(), scratch3())); 938 scratch1(), scratch2(), scratch3()));
940 ASSERT(interceptor_holder->HasNamedInterceptor()); 939 ASSERT(holder()->HasNamedInterceptor());
941 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 940 ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
942 941
943 // So far the most popular follow ups for interceptor loads are FIELD 942 // So far the most popular follow ups for interceptor loads are FIELD
944 // and CALLBACKS, so inline only them, other cases may be added later. 943 // and CALLBACKS, so inline only them, other cases may be added later.
945 bool compile_followup_inline = false; 944 bool compile_followup_inline = false;
946 if (lookup->IsFound() && lookup->IsCacheable()) { 945 if (lookup->IsFound() && lookup->IsCacheable()) {
947 if (lookup->IsField()) { 946 if (lookup->IsField()) {
948 compile_followup_inline = true; 947 compile_followup_inline = true;
949 } else if (lookup->type() == CALLBACKS && 948 } else if (lookup->type() == CALLBACKS &&
950 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 949 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
951 Handle<ExecutableAccessorInfo> callback( 950 Handle<ExecutableAccessorInfo> callback(
952 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 951 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
953 compile_followup_inline = 952 compile_followup_inline =
954 callback->getter() != NULL && 953 callback->getter() != NULL &&
955 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 954 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
956 type()); 955 type());
957 } 956 }
958 } 957 }
959 958
960 if (compile_followup_inline) { 959 if (compile_followup_inline) {
961 // Compile the interceptor call, followed by inline code to load the 960 // Compile the interceptor call, followed by inline code to load the
962 // property from further up the prototype chain if the call fails. 961 // property from further up the prototype chain if the call fails.
963 // Check that the maps haven't changed. 962 // Check that the maps haven't changed.
964 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 963 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
965 964
966 // Preserve the receiver register explicitly whenever it is different from 965 // Preserve the receiver register explicitly whenever it is different from
967 // the holder and it is needed should the interceptor return without any 966 // the holder and it is needed should the interceptor return without any
968 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 967 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
969 // the FIELD case might cause a miss during the prototype check. 968 // the FIELD case might cause a miss during the prototype check.
970 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 969 bool must_perfrom_prototype_check = *holder() != lookup->holder();
971 bool must_preserve_receiver_reg = !receiver().Is(holder_reg) && 970 bool must_preserve_receiver_reg = !receiver().Is(holder_reg) &&
972 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 971 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
973 972
974 // Save necessary data before invoking an interceptor. 973 // Save necessary data before invoking an interceptor.
975 // Requires a frame to make GC aware of pushed pointers. 974 // Requires a frame to make GC aware of pushed pointers.
976 { 975 {
977 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 976 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
978 if (must_preserve_receiver_reg) { 977 if (must_preserve_receiver_reg) {
979 __ Push(receiver(), holder_reg, this->name()); 978 __ Push(receiver(), holder_reg, this->name());
980 } else { 979 } else {
981 __ Push(holder_reg, this->name()); 980 __ Push(holder_reg, this->name());
982 } 981 }
983 // Invoke an interceptor. Note: map checks from receiver to 982 // Invoke an interceptor. Note: map checks from receiver to
984 // interceptor's holder has been compiled before (see a caller 983 // interceptor's holder has been compiled before (see a caller
985 // of this method.) 984 // of this method.)
986 CompileCallLoadPropertyWithInterceptor( 985 CompileCallLoadPropertyWithInterceptor(
987 masm(), receiver(), holder_reg, this->name(), interceptor_holder, 986 masm(), receiver(), holder_reg, this->name(), holder(),
988 IC::kLoadPropertyWithInterceptorOnly); 987 IC::kLoadPropertyWithInterceptorOnly);
989 988
990 // Check if interceptor provided a value for property. If it's 989 // Check if interceptor provided a value for property. If it's
991 // the case, return immediately. 990 // the case, return immediately.
992 Label interceptor_failed; 991 Label interceptor_failed;
993 __ JumpIfRoot(x0, 992 __ JumpIfRoot(x0,
994 Heap::kNoInterceptorResultSentinelRootIndex, 993 Heap::kNoInterceptorResultSentinelRootIndex,
995 &interceptor_failed); 994 &interceptor_failed);
996 frame_scope.GenerateLeaveFrame(); 995 frame_scope.GenerateLeaveFrame();
997 __ Ret(); 996 __ Ret();
998 997
999 __ Bind(&interceptor_failed); 998 __ Bind(&interceptor_failed);
1000 if (must_preserve_receiver_reg) { 999 if (must_preserve_receiver_reg) {
1001 __ Pop(this->name(), holder_reg, receiver()); 1000 __ Pop(this->name(), holder_reg, receiver());
1002 } else { 1001 } else {
1003 __ Pop(this->name(), holder_reg); 1002 __ Pop(this->name(), holder_reg);
1004 } 1003 }
1005 // Leave the internal frame. 1004 // Leave the internal frame.
1006 } 1005 }
1007 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 1006 GenerateLoadPostInterceptor(holder_reg, name, lookup);
1008 } else { // !compile_followup_inline 1007 } else { // !compile_followup_inline
1009 // Call the runtime system to load the interceptor. 1008 // Call the runtime system to load the interceptor.
1010 // Check that the maps haven't changed. 1009 // Check that the maps haven't changed.
1011 PushInterceptorArguments( 1010 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
1012 masm(), receiver(), holder_reg, this->name(), interceptor_holder); 1011 holder());
1013 1012
1014 ExternalReference ref = 1013 ExternalReference ref =
1015 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), 1014 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
1016 isolate()); 1015 isolate());
1017 __ TailCallExternalReference( 1016 __ TailCallExternalReference(
1018 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 1017 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
1019 } 1018 }
1020 } 1019 }
1021 1020
1022 1021
1023 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 1022 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1024 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 1023 Handle<JSObject> object, Handle<Name> name,
1025 Handle<ExecutableAccessorInfo> callback) { 1024 Handle<ExecutableAccessorInfo> callback) {
1026 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback"); 1025 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
1027 Register holder_reg = Frontend(receiver(), holder, name); 1026 Register holder_reg = Frontend(receiver(), name);
1028 1027
1029 // Stub never generated for non-global objects that require access checks. 1028 // Stub never generated for non-global objects that require access checks.
1030 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1029 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1031 1030
1032 // receiver() and holder_reg can alias. 1031 // receiver() and holder_reg can alias.
1033 ASSERT(!AreAliased(receiver(), scratch1(), scratch2(), value())); 1032 ASSERT(!AreAliased(receiver(), scratch1(), scratch2(), value()));
1034 ASSERT(!AreAliased(holder_reg, scratch1(), scratch2(), value())); 1033 ASSERT(!AreAliased(holder_reg, scratch1(), scratch2(), value()));
1035 __ Mov(scratch1(), Operand(callback)); 1034 __ Mov(scratch1(), Operand(callback));
1036 __ Mov(scratch2(), Operand(name)); 1035 __ Mov(scratch2(), Operand(name));
1037 __ Push(receiver(), holder_reg, scratch1(), scratch2(), value()); 1036 __ Push(receiver(), holder_reg, scratch1(), scratch2(), value());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 } 1089 }
1091 __ Ret(); 1090 __ Ret();
1092 } 1091 }
1093 1092
1094 1093
1095 #undef __ 1094 #undef __
1096 #define __ ACCESS_MASM(masm()) 1095 #define __ ACCESS_MASM(masm())
1097 1096
1098 1097
1099 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 1098 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1100 Handle<JSObject> object, Handle<Name> name) { 1099 Handle<Name> name) {
1101 Label miss; 1100 Label miss;
1102 1101
1103 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor"); 1102 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor");
1104 1103
1105 __ Push(receiver(), this->name(), value()); 1104 __ Push(receiver(), this->name(), value());
1106 1105
1107 // Do tail-call to the runtime system. 1106 // Do tail-call to the runtime system.
1108 ExternalReference store_ic_property = ExternalReference( 1107 ExternalReference store_ic_property = ExternalReference(
1109 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1108 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1110 __ TailCallExternalReference(store_ic_property, 3, 1); 1109 __ TailCallExternalReference(store_ic_property, 3, 1);
1111 1110
1112 // Return the generated code. 1111 // Return the generated code.
1113 return GetCode(kind(), Code::FAST, name); 1112 return GetCode(kind(), Code::FAST, name);
1114 } 1113 }
1115 1114
1116 1115
1117 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1116 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1118 Handle<JSObject> last, Handle<Name> name) { 1117 Handle<Name> name) {
1119 NonexistentFrontend(last, name); 1118 NonexistentFrontend(name);
1120 1119
1121 // Return undefined if maps of the full prototype chain are still the 1120 // Return undefined if maps of the full prototype chain are still the
1122 // same and no global property with this name contains a value. 1121 // same and no global property with this name contains a value.
1123 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 1122 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
1124 __ Ret(); 1123 __ Ret();
1125 1124
1126 // Return the generated code. 1125 // Return the generated code.
1127 return GetCode(kind(), Code::FAST, name); 1126 return GetCode(kind(), Code::FAST, name);
1128 } 1127 }
1129 1128
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 } 1197 }
1199 __ Ret(); 1198 __ Ret();
1200 } 1199 }
1201 1200
1202 1201
1203 #undef __ 1202 #undef __
1204 #define __ ACCESS_MASM(masm()) 1203 #define __ ACCESS_MASM(masm())
1205 1204
1206 1205
1207 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1206 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1208 Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name, 1207 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1209 bool is_dont_delete) {
1210 Label miss; 1208 Label miss;
1211 FrontendHeader(receiver(), global, name, &miss); 1209 FrontendHeader(receiver(), name, &miss);
1212 1210
1213 // Get the value from the cell. 1211 // Get the value from the cell.
1214 Register result = StoreIC::ValueRegister(); 1212 Register result = StoreIC::ValueRegister();
1215 __ Mov(result, Operand(cell)); 1213 __ Mov(result, Operand(cell));
1216 __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset)); 1214 __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
1217 1215
1218 // Check for deleted property if property can actually be deleted. 1216 // Check for deleted property if property can actually be deleted.
1219 if (!is_dont_delete) { 1217 if (!is_dont_delete) {
1220 __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss); 1218 __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
1221 } 1219 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 1355
1358 // Miss case, call the runtime. 1356 // Miss case, call the runtime.
1359 __ Bind(&miss); 1357 __ Bind(&miss);
1360 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1358 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1361 } 1359 }
1362 1360
1363 1361
1364 } } // namespace v8::internal 1362 } } // namespace v8::internal
1365 1363
1366 #endif // V8_TARGET_ARCH_ARM64 1364 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698