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

Side by Side Diff: src/arm/stub-cache-arm.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 | « no previous file | src/arm64/stub-cache-arm64.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_ARM 7 #if V8_TARGET_ARCH_ARM
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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 masm, miss, holder_reg, name, scratch1(), scratch2()); 304 masm, miss, holder_reg, name, scratch1(), scratch2());
305 } 305 }
306 } 306 }
307 307
308 308
309 // Generate StoreTransition code, value is passed in r0 register. 309 // Generate StoreTransition code, value is passed in r0 register.
310 // When leaving generated code after success, the receiver_reg and name_reg 310 // When leaving generated code after success, the receiver_reg and name_reg
311 // may be clobbered. Upon branch to miss_label, the receiver and name 311 // may be clobbered. Upon branch to miss_label, the receiver and name
312 // registers have their original values. 312 // registers have their original values.
313 void NamedStoreHandlerCompiler::GenerateStoreTransition( 313 void NamedStoreHandlerCompiler::GenerateStoreTransition(
314 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 314 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition,
315 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 315 Handle<Name> name, Register receiver_reg, Register storage_reg,
316 Register storage_reg, Register value_reg, Register scratch1, 316 Register value_reg, Register scratch1, Register scratch2, Register scratch3,
317 Register scratch2, Register scratch3, Label* miss_label, Label* slow) { 317 Label* miss_label, Label* slow) {
318 // r0 : value 318 // r0 : value
319 Label exit; 319 Label exit;
320 320
321 int descriptor = transition->LastAdded(); 321 int descriptor = transition->LastAdded();
322 DescriptorArray* descriptors = transition->instance_descriptors(); 322 DescriptorArray* descriptors = transition->instance_descriptors();
323 PropertyDetails details = descriptors->GetDetails(descriptor); 323 PropertyDetails details = descriptors->GetDetails(descriptor);
324 Representation representation = details.representation(); 324 Representation representation = details.representation();
325 ASSERT(!representation.IsNone()); 325 ASSERT(!representation.IsNone());
326 326
327 if (details.type() == CONSTANT) { 327 if (details.type() == CONSTANT) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 363
364 __ bind(&heap_number); 364 __ bind(&heap_number);
365 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 365 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
366 miss_label, DONT_DO_SMI_CHECK); 366 miss_label, DONT_DO_SMI_CHECK);
367 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 367 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
368 368
369 __ bind(&do_store); 369 __ bind(&do_store);
370 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 370 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
371 } 371 }
372 372
373 // Stub never generated for non-global objects that require access 373 // Stub never generated for objects that require access checks.
374 // checks. 374 ASSERT(!transition->is_access_check_needed());
375 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
376 375
377 // Perform map transition for the receiver if necessary. 376 // Perform map transition for the receiver if necessary.
378 if (details.type() == FIELD && 377 if (details.type() == FIELD &&
379 object->map()->unused_property_fields() == 0) { 378 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
380 // The properties must be extended before we can store the value. 379 // The properties must be extended before we can store the value.
381 // We jump to a runtime call that extends the properties array. 380 // We jump to a runtime call that extends the properties array.
382 __ push(receiver_reg); 381 __ push(receiver_reg);
383 __ mov(r2, Operand(transition)); 382 __ mov(r2, Operand(transition));
384 __ Push(r2, r0); 383 __ Push(r2, r0);
385 __ TailCallExternalReference( 384 __ TailCallExternalReference(
386 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 385 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
387 masm->isolate()), 386 masm->isolate()),
388 3, 387 3,
389 1); 388 1);
(...skipping 19 matching lines...) Expand all
409 __ Ret(); 408 __ Ret();
410 return; 409 return;
411 } 410 }
412 411
413 int index = transition->instance_descriptors()->GetFieldIndex( 412 int index = transition->instance_descriptors()->GetFieldIndex(
414 transition->LastAdded()); 413 transition->LastAdded());
415 414
416 // Adjust for the number of properties stored in the object. Even in the 415 // Adjust for the number of properties stored in the object. Even in the
417 // face of a transition we can use the old map here because the size of the 416 // face of a transition we can use the old map here because the size of the
418 // object and the number of in-object properties is not going to change. 417 // object and the number of in-object properties is not going to change.
419 index -= object->map()->inobject_properties(); 418 index -= transition->inobject_properties();
420 419
421 // TODO(verwaest): Share this code as a code stub. 420 // TODO(verwaest): Share this code as a code stub.
422 SmiCheck smi_check = representation.IsTagged() 421 SmiCheck smi_check = representation.IsTagged()
423 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 422 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
424 if (index < 0) { 423 if (index < 0) {
425 // Set the property straight into the object. 424 // Set the property straight into the object.
426 int offset = object->map()->instance_size() + (index * kPointerSize); 425 int offset = transition->instance_size() + (index * kPointerSize);
427 if (representation.IsDouble()) { 426 if (representation.IsDouble()) {
428 __ str(storage_reg, FieldMemOperand(receiver_reg, offset)); 427 __ str(storage_reg, FieldMemOperand(receiver_reg, offset));
429 } else { 428 } else {
430 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 429 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
431 } 430 }
432 431
433 if (!representation.IsSmi()) { 432 if (!representation.IsSmi()) {
434 // Update the write barrier for the array address. 433 // Update the write barrier for the array address.
435 if (!representation.IsDouble()) { 434 if (!representation.IsDouble()) {
436 __ mov(storage_reg, value_reg); 435 __ mov(storage_reg, value_reg);
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 Handle<Code> code) { 725 Handle<Code> code) {
727 __ Jump(code, RelocInfo::CODE_TARGET); 726 __ Jump(code, RelocInfo::CODE_TARGET);
728 } 727 }
729 728
730 729
731 #undef __ 730 #undef __
732 #define __ ACCESS_MASM(masm()) 731 #define __ ACCESS_MASM(masm())
733 732
734 733
735 Register PropertyHandlerCompiler::CheckPrototypes( 734 Register PropertyHandlerCompiler::CheckPrototypes(
736 Register object_reg, Handle<JSObject> holder, Register holder_reg, 735 Register object_reg, Register holder_reg, Register scratch1,
737 Register scratch1, Register scratch2, Handle<Name> name, Label* miss, 736 Register scratch2, Handle<Name> name, Label* miss,
738 PrototypeCheckType check) { 737 PrototypeCheckType check) {
739 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 738 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
740 739
741 // Make sure there's no overlap between holder and object registers. 740 // Make sure there's no overlap between holder and object registers.
742 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 741 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
743 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 742 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
744 && !scratch2.is(scratch1)); 743 && !scratch2.is(scratch1));
745 744
746 // Keep track of the current object in register reg. 745 // Keep track of the current object in register reg.
747 Register reg = object_reg; 746 Register reg = object_reg;
748 int depth = 0; 747 int depth = 0;
749 748
750 Handle<JSObject> current = Handle<JSObject>::null(); 749 Handle<JSObject> current = Handle<JSObject>::null();
751 if (type()->IsConstant()) { 750 if (type()->IsConstant()) {
752 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 751 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
753 } 752 }
754 Handle<JSObject> prototype = Handle<JSObject>::null(); 753 Handle<JSObject> prototype = Handle<JSObject>::null();
755 Handle<Map> current_map = receiver_map; 754 Handle<Map> current_map = receiver_map;
756 Handle<Map> holder_map(holder->map()); 755 Handle<Map> holder_map(holder()->map());
757 // Traverse the prototype chain and check the maps in the prototype chain for 756 // Traverse the prototype chain and check the maps in the prototype chain for
758 // fast and global objects or do negative lookup for normal objects. 757 // fast and global objects or do negative lookup for normal objects.
759 while (!current_map.is_identical_to(holder_map)) { 758 while (!current_map.is_identical_to(holder_map)) {
760 ++depth; 759 ++depth;
761 760
762 // Only global objects and objects that do not require access 761 // Only global objects and objects that do not require access
763 // checks are allowed in stubs. 762 // checks are allowed in stubs.
764 ASSERT(current_map->IsJSGlobalProxyMap() || 763 ASSERT(current_map->IsJSGlobalProxyMap() ||
765 !current_map->is_access_check_needed()); 764 !current_map->is_access_check_needed());
766 765
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 Label success; 857 Label success;
859 __ b(&success); 858 __ b(&success);
860 GenerateRestoreName(masm(), miss, name); 859 GenerateRestoreName(masm(), miss, name);
861 TailCallBuiltin(masm(), MissBuiltin(kind())); 860 TailCallBuiltin(masm(), MissBuiltin(kind()));
862 __ bind(&success); 861 __ bind(&success);
863 } 862 }
864 } 863 }
865 864
866 865
867 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 866 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
868 Handle<JSObject> holder,
869 Handle<Name> name, 867 Handle<Name> name,
870 Handle<Object> callback) { 868 Handle<Object> callback) {
871 Label miss; 869 Label miss;
872 870
873 Register reg = FrontendHeader(object_reg, holder, name, &miss); 871 Register reg = FrontendHeader(object_reg, name, &miss);
874 872
875 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 873 if (!holder()->HasFastProperties()) {
874 ASSERT(!holder()->IsGlobalObject());
876 ASSERT(!reg.is(scratch2())); 875 ASSERT(!reg.is(scratch2()));
877 ASSERT(!reg.is(scratch3())); 876 ASSERT(!reg.is(scratch3()));
878 ASSERT(!reg.is(scratch4())); 877 ASSERT(!reg.is(scratch4()));
879 878
880 // Load the properties dictionary. 879 // Load the properties dictionary.
881 Register dictionary = scratch4(); 880 Register dictionary = scratch4();
882 __ ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 881 __ ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
883 882
884 // Probe the dictionary. 883 // Probe the dictionary.
885 Label probe_done; 884 Label probe_done;
(...skipping 16 matching lines...) Expand all
902 __ cmp(scratch2(), Operand(callback)); 901 __ cmp(scratch2(), Operand(callback));
903 __ b(ne, &miss); 902 __ b(ne, &miss);
904 } 903 }
905 904
906 FrontendFooter(name, &miss); 905 FrontendFooter(name, &miss);
907 return reg; 906 return reg;
908 } 907 }
909 908
910 909
911 void NamedLoadHandlerCompiler::GenerateLoadField( 910 void NamedLoadHandlerCompiler::GenerateLoadField(
912 Register reg, Handle<JSObject> holder, FieldIndex field, 911 Register reg, FieldIndex field, Representation representation) {
913 Representation representation) {
914 if (!reg.is(receiver())) __ mov(receiver(), reg); 912 if (!reg.is(receiver())) __ mov(receiver(), reg);
915 LoadFieldStub stub(isolate(), field); 913 LoadFieldStub stub(isolate(), field);
916 GenerateTailCall(masm(), stub.GetCode()); 914 GenerateTailCall(masm(), stub.GetCode());
917 } 915 }
918 916
919 917
920 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 918 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
921 // Return the constant value. 919 // Return the constant value.
922 __ Move(r0, value); 920 __ Move(r0, value);
923 __ Ret(); 921 __ Ret();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 ApiFunction fun(getter_address); 961 ApiFunction fun(getter_address);
964 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 962 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
965 ExternalReference ref = ExternalReference(&fun, type, isolate()); 963 ExternalReference ref = ExternalReference(&fun, type, isolate());
966 __ mov(getter_address_reg, Operand(ref)); 964 __ mov(getter_address_reg, Operand(ref));
967 965
968 CallApiGetterStub stub(isolate()); 966 CallApiGetterStub stub(isolate());
969 __ TailCallStub(&stub); 967 __ TailCallStub(&stub);
970 } 968 }
971 969
972 970
973 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 971 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
974 Register holder_reg, Handle<JSObject> interceptor_holder, 972 LookupResult* lookup,
975 LookupResult* lookup, Handle<Name> name) { 973 Handle<Name> name) {
976 ASSERT(interceptor_holder->HasNamedInterceptor()); 974 ASSERT(holder()->HasNamedInterceptor());
977 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 975 ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
978 976
979 // So far the most popular follow ups for interceptor loads are FIELD 977 // So far the most popular follow ups for interceptor loads are FIELD
980 // and CALLBACKS, so inline only them, other cases may be added 978 // and CALLBACKS, so inline only them, other cases may be added
981 // later. 979 // later.
982 bool compile_followup_inline = false; 980 bool compile_followup_inline = false;
983 if (lookup->IsFound() && lookup->IsCacheable()) { 981 if (lookup->IsFound() && lookup->IsCacheable()) {
984 if (lookup->IsField()) { 982 if (lookup->IsField()) {
985 compile_followup_inline = true; 983 compile_followup_inline = true;
986 } else if (lookup->type() == CALLBACKS && 984 } else if (lookup->type() == CALLBACKS &&
987 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 985 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
988 Handle<ExecutableAccessorInfo> callback( 986 Handle<ExecutableAccessorInfo> callback(
989 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 987 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
990 compile_followup_inline = 988 compile_followup_inline =
991 callback->getter() != NULL && 989 callback->getter() != NULL &&
992 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 990 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
993 type()); 991 type());
994 } 992 }
995 } 993 }
996 994
997 if (compile_followup_inline) { 995 if (compile_followup_inline) {
998 // Compile the interceptor call, followed by inline code to load the 996 // Compile the interceptor call, followed by inline code to load the
999 // property from further up the prototype chain if the call fails. 997 // property from further up the prototype chain if the call fails.
1000 // Check that the maps haven't changed. 998 // Check that the maps haven't changed.
1001 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 999 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
1002 1000
1003 // Preserve the receiver register explicitly whenever it is different from 1001 // Preserve the receiver register explicitly whenever it is different from
1004 // the holder and it is needed should the interceptor return without any 1002 // the holder and it is needed should the interceptor return without any
1005 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 1003 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
1006 // the FIELD case might cause a miss during the prototype check. 1004 // the FIELD case might cause a miss during the prototype check.
1007 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 1005 bool must_perfrom_prototype_check = *holder() != lookup->holder();
1008 bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 1006 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
1009 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 1007 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
1010 1008
1011 // Save necessary data before invoking an interceptor. 1009 // Save necessary data before invoking an interceptor.
1012 // Requires a frame to make GC aware of pushed pointers. 1010 // Requires a frame to make GC aware of pushed pointers.
1013 { 1011 {
1014 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); 1012 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
1015 if (must_preserve_receiver_reg) { 1013 if (must_preserve_receiver_reg) {
1016 __ Push(receiver(), holder_reg, this->name()); 1014 __ Push(receiver(), holder_reg, this->name());
1017 } else { 1015 } else {
1018 __ Push(holder_reg, this->name()); 1016 __ Push(holder_reg, this->name());
1019 } 1017 }
1020 // Invoke an interceptor. Note: map checks from receiver to 1018 // Invoke an interceptor. Note: map checks from receiver to
1021 // interceptor's holder has been compiled before (see a caller 1019 // interceptor's holder has been compiled before (see a caller
1022 // of this method.) 1020 // of this method.)
1023 CompileCallLoadPropertyWithInterceptor( 1021 CompileCallLoadPropertyWithInterceptor(
1024 masm(), receiver(), holder_reg, this->name(), interceptor_holder, 1022 masm(), receiver(), holder_reg, this->name(), holder(),
1025 IC::kLoadPropertyWithInterceptorOnly); 1023 IC::kLoadPropertyWithInterceptorOnly);
1026 1024
1027 // Check if interceptor provided a value for property. If it's 1025 // Check if interceptor provided a value for property. If it's
1028 // the case, return immediately. 1026 // the case, return immediately.
1029 Label interceptor_failed; 1027 Label interceptor_failed;
1030 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 1028 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
1031 __ cmp(r0, scratch1()); 1029 __ cmp(r0, scratch1());
1032 __ b(eq, &interceptor_failed); 1030 __ b(eq, &interceptor_failed);
1033 frame_scope.GenerateLeaveFrame(); 1031 frame_scope.GenerateLeaveFrame();
1034 __ Ret(); 1032 __ Ret();
1035 1033
1036 __ bind(&interceptor_failed); 1034 __ bind(&interceptor_failed);
1037 __ pop(this->name()); 1035 __ pop(this->name());
1038 __ pop(holder_reg); 1036 __ pop(holder_reg);
1039 if (must_preserve_receiver_reg) { 1037 if (must_preserve_receiver_reg) {
1040 __ pop(receiver()); 1038 __ pop(receiver());
1041 } 1039 }
1042 // Leave the internal frame. 1040 // Leave the internal frame.
1043 } 1041 }
1044 1042
1045 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 1043 GenerateLoadPostInterceptor(holder_reg, name, lookup);
1046 } else { // !compile_followup_inline 1044 } else { // !compile_followup_inline
1047 // Call the runtime system to load the interceptor. 1045 // Call the runtime system to load the interceptor.
1048 // Check that the maps haven't changed. 1046 // Check that the maps haven't changed.
1049 PushInterceptorArguments(masm(), receiver(), holder_reg, 1047 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
1050 this->name(), interceptor_holder); 1048 holder());
1051 1049
1052 ExternalReference ref = 1050 ExternalReference ref =
1053 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), 1051 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor),
1054 isolate()); 1052 isolate());
1055 __ TailCallExternalReference( 1053 __ TailCallExternalReference(
1056 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 1054 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
1057 } 1055 }
1058 } 1056 }
1059 1057
1060 1058
1061 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 1059 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1062 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 1060 Handle<JSObject> object, Handle<Name> name,
1063 Handle<ExecutableAccessorInfo> callback) { 1061 Handle<ExecutableAccessorInfo> callback) {
1064 Register holder_reg = Frontend(receiver(), holder, name); 1062 Register holder_reg = Frontend(receiver(), name);
1065
1066 // Stub never generated for non-global objects that require access checks.
1067 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1068 1063
1069 __ push(receiver()); // receiver 1064 __ push(receiver()); // receiver
1070 __ push(holder_reg); 1065 __ push(holder_reg);
1071 __ mov(ip, Operand(callback)); // callback info 1066 __ mov(ip, Operand(callback)); // callback info
1072 __ push(ip); 1067 __ push(ip);
1073 __ mov(ip, Operand(name)); 1068 __ mov(ip, Operand(name));
1074 __ Push(ip, value()); 1069 __ Push(ip, value());
1075 1070
1076 // Do tail-call to the runtime system. 1071 // Do tail-call to the runtime system.
1077 ExternalReference store_callback_property = 1072 ExternalReference store_callback_property =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 } 1120 }
1126 __ Ret(); 1121 __ Ret();
1127 } 1122 }
1128 1123
1129 1124
1130 #undef __ 1125 #undef __
1131 #define __ ACCESS_MASM(masm()) 1126 #define __ ACCESS_MASM(masm())
1132 1127
1133 1128
1134 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 1129 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1135 Handle<JSObject> object, Handle<Name> name) { 1130 Handle<Name> name) {
1136 __ Push(receiver(), this->name(), value()); 1131 __ Push(receiver(), this->name(), value());
1137 1132
1138 // Do tail-call to the runtime system. 1133 // Do tail-call to the runtime system.
1139 ExternalReference store_ic_property = ExternalReference( 1134 ExternalReference store_ic_property = ExternalReference(
1140 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1135 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1141 __ TailCallExternalReference(store_ic_property, 3, 1); 1136 __ TailCallExternalReference(store_ic_property, 3, 1);
1142 1137
1143 // Return the generated code. 1138 // Return the generated code.
1144 return GetCode(kind(), Code::FAST, name); 1139 return GetCode(kind(), Code::FAST, name);
1145 } 1140 }
1146 1141
1147 1142
1148 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1143 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1149 Handle<JSObject> last, Handle<Name> name) { 1144 Handle<Name> name) {
1150 NonexistentFrontend(last, name); 1145 NonexistentFrontend(name);
1151 1146
1152 // Return undefined if maps of the full prototype chain are still the 1147 // Return undefined if maps of the full prototype chain are still the
1153 // same and no global property with this name contains a value. 1148 // same and no global property with this name contains a value.
1154 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1149 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1155 __ Ret(); 1150 __ Ret();
1156 1151
1157 // Return the generated code. 1152 // Return the generated code.
1158 return GetCode(kind(), Code::FAST, name); 1153 return GetCode(kind(), Code::FAST, name);
1159 } 1154 }
1160 1155
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 } 1223 }
1229 __ Ret(); 1224 __ Ret();
1230 } 1225 }
1231 1226
1232 1227
1233 #undef __ 1228 #undef __
1234 #define __ ACCESS_MASM(masm()) 1229 #define __ ACCESS_MASM(masm())
1235 1230
1236 1231
1237 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1232 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1238 Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name, 1233 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1239 bool is_dont_delete) {
1240 Label miss; 1234 Label miss;
1241 FrontendHeader(receiver(), global, name, &miss); 1235 FrontendHeader(receiver(), name, &miss);
1242 1236
1243 // Get the value from the cell. 1237 // Get the value from the cell.
1244 Register result = StoreIC::ValueRegister(); 1238 Register result = StoreIC::ValueRegister();
1245 __ mov(result, Operand(cell)); 1239 __ mov(result, Operand(cell));
1246 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); 1240 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
1247 1241
1248 // Check for deleted property if property can actually be deleted. 1242 // Check for deleted property if property can actually be deleted.
1249 if (!is_dont_delete) { 1243 if (!is_dont_delete) {
1250 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 1244 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1251 __ cmp(result, ip); 1245 __ cmp(result, ip);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 1386
1393 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1387 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1394 } 1388 }
1395 1389
1396 1390
1397 #undef __ 1391 #undef __
1398 1392
1399 } } // namespace v8::internal 1393 } } // namespace v8::internal
1400 1394
1401 #endif // V8_TARGET_ARCH_ARM 1395 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/stub-cache-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698