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

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

Issue 435643002: Version 3.28.51.1 (merged r22708, r22723, r22724) (Closed) Base URL: https://v8.googlecode.com/svn/trunk
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/mips/ic-mips.cc ('k') | src/mips64/ic-mips64.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_MIPS 7 #if V8_TARGET_ARCH_MIPS
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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 GenerateDictionaryNegativeLookup( 290 GenerateDictionaryNegativeLookup(
291 masm, miss, holder_reg, name, scratch1(), scratch2()); 291 masm, miss, holder_reg, name, scratch1(), scratch2());
292 } 292 }
293 } 293 }
294 294
295 295
296 // Generate StoreTransition code, value is passed in a0 register. 296 // Generate StoreTransition code, value is passed in a0 register.
297 // After executing generated code, the receiver_reg and name_reg 297 // After executing generated code, the receiver_reg and name_reg
298 // may be clobbered. 298 // may be clobbered.
299 void NamedStoreHandlerCompiler::GenerateStoreTransition( 299 void NamedStoreHandlerCompiler::GenerateStoreTransition(
300 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 300 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition,
301 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 301 Handle<Name> name, Register receiver_reg, Register storage_reg,
302 Register storage_reg, Register value_reg, Register scratch1, 302 Register value_reg, Register scratch1, Register scratch2, Register scratch3,
303 Register scratch2, Register scratch3, Label* miss_label, Label* slow) { 303 Label* miss_label, Label* slow) {
304 // a0 : value. 304 // a0 : value.
305 Label exit; 305 Label exit;
306 306
307 int descriptor = transition->LastAdded(); 307 int descriptor = transition->LastAdded();
308 DescriptorArray* descriptors = transition->instance_descriptors(); 308 DescriptorArray* descriptors = transition->instance_descriptors();
309 PropertyDetails details = descriptors->GetDetails(descriptor); 309 PropertyDetails details = descriptors->GetDetails(descriptor);
310 Representation representation = details.representation(); 310 Representation representation = details.representation();
311 ASSERT(!representation.IsNone()); 311 ASSERT(!representation.IsNone());
312 312
313 if (details.type() == CONSTANT) { 313 if (details.type() == CONSTANT) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 350
351 __ bind(&heap_number); 351 __ bind(&heap_number);
352 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 352 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
353 miss_label, DONT_DO_SMI_CHECK); 353 miss_label, DONT_DO_SMI_CHECK);
354 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 354 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
355 355
356 __ bind(&do_store); 356 __ bind(&do_store);
357 __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 357 __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
358 } 358 }
359 359
360 // Stub never generated for non-global objects that require access 360 // Stub never generated for objects that require access checks.
361 // checks. 361 ASSERT(!transition->is_access_check_needed());
362 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
363 362
364 // Perform map transition for the receiver if necessary. 363 // Perform map transition for the receiver if necessary.
365 if (details.type() == FIELD && 364 if (details.type() == FIELD &&
366 object->map()->unused_property_fields() == 0) { 365 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
367 // The properties must be extended before we can store the value. 366 // The properties must be extended before we can store the value.
368 // We jump to a runtime call that extends the properties array. 367 // We jump to a runtime call that extends the properties array.
369 __ push(receiver_reg); 368 __ push(receiver_reg);
370 __ li(a2, Operand(transition)); 369 __ li(a2, Operand(transition));
371 __ Push(a2, a0); 370 __ Push(a2, a0);
372 __ TailCallExternalReference( 371 __ TailCallExternalReference(
373 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 372 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
374 masm->isolate()), 373 masm->isolate()),
375 3, 1); 374 3, 1);
376 return; 375 return;
(...skipping 19 matching lines...) Expand all
396 __ mov(v0, a0); 395 __ mov(v0, a0);
397 return; 396 return;
398 } 397 }
399 398
400 int index = transition->instance_descriptors()->GetFieldIndex( 399 int index = transition->instance_descriptors()->GetFieldIndex(
401 transition->LastAdded()); 400 transition->LastAdded());
402 401
403 // Adjust for the number of properties stored in the object. Even in the 402 // Adjust for the number of properties stored in the object. Even in the
404 // face of a transition we can use the old map here because the size of the 403 // face of a transition we can use the old map here because the size of the
405 // object and the number of in-object properties is not going to change. 404 // object and the number of in-object properties is not going to change.
406 index -= object->map()->inobject_properties(); 405 index -= transition->inobject_properties();
407 406
408 // TODO(verwaest): Share this code as a code stub. 407 // TODO(verwaest): Share this code as a code stub.
409 SmiCheck smi_check = representation.IsTagged() 408 SmiCheck smi_check = representation.IsTagged()
410 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 409 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
411 if (index < 0) { 410 if (index < 0) {
412 // Set the property straight into the object. 411 // Set the property straight into the object.
413 int offset = object->map()->instance_size() + (index * kPointerSize); 412 int offset = transition->instance_size() + (index * kPointerSize);
414 if (representation.IsDouble()) { 413 if (representation.IsDouble()) {
415 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset)); 414 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset));
416 } else { 415 } else {
417 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); 416 __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
418 } 417 }
419 418
420 if (!representation.IsSmi()) { 419 if (!representation.IsSmi()) {
421 // Update the write barrier for the array address. 420 // Update the write barrier for the array address.
422 if (!representation.IsDouble()) { 421 if (!representation.IsDouble()) {
423 __ mov(storage_reg, value_reg); 422 __ mov(storage_reg, value_reg);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 Handle<Code> code) { 717 Handle<Code> code) {
719 __ Jump(code, RelocInfo::CODE_TARGET); 718 __ Jump(code, RelocInfo::CODE_TARGET);
720 } 719 }
721 720
722 721
723 #undef __ 722 #undef __
724 #define __ ACCESS_MASM(masm()) 723 #define __ ACCESS_MASM(masm())
725 724
726 725
727 Register PropertyHandlerCompiler::CheckPrototypes( 726 Register PropertyHandlerCompiler::CheckPrototypes(
728 Handle<HeapType> type, Register object_reg, Handle<JSObject> holder, 727 Register object_reg, Register holder_reg, Register scratch1,
729 Register holder_reg, Register scratch1, Register scratch2, 728 Register scratch2, Handle<Name> name, Label* miss,
730 Handle<Name> name, Label* miss, PrototypeCheckType check) { 729 PrototypeCheckType check) {
731 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 730 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
732 731
733 // Make sure there's no overlap between holder and object registers. 732 // Make sure there's no overlap between holder and object registers.
734 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 733 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
735 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 734 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
736 && !scratch2.is(scratch1)); 735 && !scratch2.is(scratch1));
737 736
738 // Keep track of the current object in register reg. 737 // Keep track of the current object in register reg.
739 Register reg = object_reg; 738 Register reg = object_reg;
740 int depth = 0; 739 int depth = 0;
741 740
742 Handle<JSObject> current = Handle<JSObject>::null(); 741 Handle<JSObject> current = Handle<JSObject>::null();
743 if (type->IsConstant()) { 742 if (type()->IsConstant()) {
744 current = Handle<JSObject>::cast(type->AsConstant()->Value()); 743 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
745 } 744 }
746 Handle<JSObject> prototype = Handle<JSObject>::null(); 745 Handle<JSObject> prototype = Handle<JSObject>::null();
747 Handle<Map> current_map = receiver_map; 746 Handle<Map> current_map = receiver_map;
748 Handle<Map> holder_map(holder->map()); 747 Handle<Map> holder_map(holder()->map());
749 // Traverse the prototype chain and check the maps in the prototype chain for 748 // Traverse the prototype chain and check the maps in the prototype chain for
750 // fast and global objects or do negative lookup for normal objects. 749 // fast and global objects or do negative lookup for normal objects.
751 while (!current_map.is_identical_to(holder_map)) { 750 while (!current_map.is_identical_to(holder_map)) {
752 ++depth; 751 ++depth;
753 752
754 // Only global objects and objects that do not require access 753 // Only global objects and objects that do not require access
755 // checks are allowed in stubs. 754 // checks are allowed in stubs.
756 ASSERT(current_map->IsJSGlobalProxyMap() || 755 ASSERT(current_map->IsJSGlobalProxyMap() ||
757 !current_map->is_access_check_needed()); 756 !current_map->is_access_check_needed());
758 757
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 if (!miss->is_unused()) { 848 if (!miss->is_unused()) {
850 Label success; 849 Label success;
851 __ Branch(&success); 850 __ Branch(&success);
852 GenerateRestoreName(masm(), miss, name); 851 GenerateRestoreName(masm(), miss, name);
853 TailCallBuiltin(masm(), MissBuiltin(kind())); 852 TailCallBuiltin(masm(), MissBuiltin(kind()));
854 __ bind(&success); 853 __ bind(&success);
855 } 854 }
856 } 855 }
857 856
858 857
859 Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type, 858 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
860 Register object_reg,
861 Handle<JSObject> holder,
862 Handle<Name> name, 859 Handle<Name> name,
863 Handle<Object> callback) { 860 Handle<Object> callback) {
864 Label miss; 861 Label miss;
865 862
866 Register reg = FrontendHeader(type, object_reg, holder, name, &miss); 863 Register reg = FrontendHeader(object_reg, name, &miss);
867 864
868 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 865 if (!holder()->HasFastProperties()) {
866 ASSERT(!holder()->IsGlobalObject());
869 ASSERT(!reg.is(scratch2())); 867 ASSERT(!reg.is(scratch2()));
870 ASSERT(!reg.is(scratch3())); 868 ASSERT(!reg.is(scratch3()));
871 ASSERT(!reg.is(scratch4())); 869 ASSERT(!reg.is(scratch4()));
872 870
873 // Load the properties dictionary. 871 // Load the properties dictionary.
874 Register dictionary = scratch4(); 872 Register dictionary = scratch4();
875 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 873 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
876 874
877 // Probe the dictionary. 875 // Probe the dictionary.
878 Label probe_done; 876 Label probe_done;
(...skipping 15 matching lines...) Expand all
894 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); 892 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset));
895 __ Branch(&miss, ne, scratch2(), Operand(callback)); 893 __ Branch(&miss, ne, scratch2(), Operand(callback));
896 } 894 }
897 895
898 FrontendFooter(name, &miss); 896 FrontendFooter(name, &miss);
899 return reg; 897 return reg;
900 } 898 }
901 899
902 900
903 void NamedLoadHandlerCompiler::GenerateLoadField( 901 void NamedLoadHandlerCompiler::GenerateLoadField(
904 Register reg, Handle<JSObject> holder, FieldIndex field, 902 Register reg, FieldIndex field, Representation representation) {
905 Representation representation) {
906 if (!reg.is(receiver())) __ mov(receiver(), reg); 903 if (!reg.is(receiver())) __ mov(receiver(), reg);
907 LoadFieldStub stub(isolate(), field); 904 LoadFieldStub stub(isolate(), field);
908 GenerateTailCall(masm(), stub.GetCode()); 905 GenerateTailCall(masm(), stub.GetCode());
909 } 906 }
910 907
911 908
912 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 909 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
913 // Return the constant value. 910 // Return the constant value.
914 __ li(v0, value); 911 __ li(v0, value);
915 __ Ret(); 912 __ Ret();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 ApiFunction fun(getter_address); 955 ApiFunction fun(getter_address);
959 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 956 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
960 ExternalReference ref = ExternalReference(&fun, type, isolate()); 957 ExternalReference ref = ExternalReference(&fun, type, isolate());
961 __ li(getter_address_reg, Operand(ref)); 958 __ li(getter_address_reg, Operand(ref));
962 959
963 CallApiGetterStub stub(isolate()); 960 CallApiGetterStub stub(isolate());
964 __ TailCallStub(&stub); 961 __ TailCallStub(&stub);
965 } 962 }
966 963
967 964
968 void NamedLoadHandlerCompiler::GenerateLoadInterceptor( 965 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
969 Register holder_reg, Handle<Object> object, 966 LookupResult* lookup,
970 Handle<JSObject> interceptor_holder, LookupResult* lookup, 967 Handle<Name> name) {
971 Handle<Name> name) { 968 ASSERT(holder()->HasNamedInterceptor());
972 ASSERT(interceptor_holder->HasNamedInterceptor()); 969 ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
973 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
974 970
975 // So far the most popular follow ups for interceptor loads are FIELD 971 // So far the most popular follow ups for interceptor loads are FIELD
976 // and CALLBACKS, so inline only them, other cases may be added 972 // and CALLBACKS, so inline only them, other cases may be added
977 // later. 973 // later.
978 bool compile_followup_inline = false; 974 bool compile_followup_inline = false;
979 if (lookup->IsFound() && lookup->IsCacheable()) { 975 if (lookup->IsFound() && lookup->IsCacheable()) {
980 if (lookup->IsField()) { 976 if (lookup->IsField()) {
981 compile_followup_inline = true; 977 compile_followup_inline = true;
982 } else if (lookup->type() == CALLBACKS && 978 } else if (lookup->type() == CALLBACKS &&
983 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 979 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
984 ExecutableAccessorInfo* callback = 980 Handle<ExecutableAccessorInfo> callback(
985 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); 981 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
986 compile_followup_inline = callback->getter() != NULL && 982 compile_followup_inline =
987 callback->IsCompatibleReceiver(*object); 983 callback->getter() != NULL &&
984 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
985 type());
988 } 986 }
989 } 987 }
990 988
991 if (compile_followup_inline) { 989 if (compile_followup_inline) {
992 // Compile the interceptor call, followed by inline code to load the 990 // Compile the interceptor call, followed by inline code to load the
993 // property from further up the prototype chain if the call fails. 991 // property from further up the prototype chain if the call fails.
994 // Check that the maps haven't changed. 992 // Check that the maps haven't changed.
995 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 993 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
996 994
997 // Preserve the receiver register explicitly whenever it is different from 995 // Preserve the receiver register explicitly whenever it is different from
998 // the holder and it is needed should the interceptor return without any 996 // the holder and it is needed should the interceptor return without any
999 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 997 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
1000 // the FIELD case might cause a miss during the prototype check. 998 // the FIELD case might cause a miss during the prototype check.
1001 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 999 bool must_perfrom_prototype_check = *holder() != lookup->holder();
1002 bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 1000 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
1003 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 1001 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
1004 1002
1005 // Save necessary data before invoking an interceptor. 1003 // Save necessary data before invoking an interceptor.
1006 // Requires a frame to make GC aware of pushed pointers. 1004 // Requires a frame to make GC aware of pushed pointers.
1007 { 1005 {
1008 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1006 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
1009 if (must_preserve_receiver_reg) { 1007 if (must_preserve_receiver_reg) {
1010 __ Push(receiver(), holder_reg, this->name()); 1008 __ Push(receiver(), holder_reg, this->name());
1011 } else { 1009 } else {
1012 __ Push(holder_reg, this->name()); 1010 __ Push(holder_reg, this->name());
1013 } 1011 }
1014 // Invoke an interceptor. Note: map checks from receiver to 1012 // Invoke an interceptor. Note: map checks from receiver to
1015 // interceptor's holder has been compiled before (see a caller 1013 // interceptor's holder has been compiled before (see a caller
1016 // of this method). 1014 // of this method).
1017 CompileCallLoadPropertyWithInterceptor( 1015 CompileCallLoadPropertyWithInterceptor(
1018 masm(), receiver(), holder_reg, this->name(), interceptor_holder, 1016 masm(), receiver(), holder_reg, this->name(), holder(),
1019 IC::kLoadPropertyWithInterceptorOnly); 1017 IC::kLoadPropertyWithInterceptorOnly);
1020 1018
1021 // Check if interceptor provided a value for property. If it's 1019 // Check if interceptor provided a value for property. If it's
1022 // the case, return immediately. 1020 // the case, return immediately.
1023 Label interceptor_failed; 1021 Label interceptor_failed;
1024 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 1022 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
1025 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); 1023 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
1026 frame_scope.GenerateLeaveFrame(); 1024 frame_scope.GenerateLeaveFrame();
1027 __ Ret(); 1025 __ Ret();
1028 1026
1029 __ bind(&interceptor_failed); 1027 __ bind(&interceptor_failed);
1030 __ pop(this->name()); 1028 __ pop(this->name());
1031 __ pop(holder_reg); 1029 __ pop(holder_reg);
1032 if (must_preserve_receiver_reg) { 1030 if (must_preserve_receiver_reg) {
1033 __ pop(receiver()); 1031 __ pop(receiver());
1034 } 1032 }
1035 // Leave the internal frame. 1033 // Leave the internal frame.
1036 } 1034 }
1037 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 1035 GenerateLoadPostInterceptor(holder_reg, name, lookup);
1038 } else { // !compile_followup_inline 1036 } else { // !compile_followup_inline
1039 // Call the runtime system to load the interceptor. 1037 // Call the runtime system to load the interceptor.
1040 // Check that the maps haven't changed. 1038 // Check that the maps haven't changed.
1041 PushInterceptorArguments(masm(), receiver(), holder_reg, 1039 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
1042 this->name(), interceptor_holder); 1040 holder());
1043 1041
1044 ExternalReference ref = ExternalReference( 1042 ExternalReference ref = ExternalReference(
1045 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 1043 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
1046 __ TailCallExternalReference( 1044 __ TailCallExternalReference(
1047 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 1045 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
1048 } 1046 }
1049 } 1047 }
1050 1048
1051 1049
1052 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 1050 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
1053 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, 1051 Handle<JSObject> object, Handle<Name> name,
1054 Handle<ExecutableAccessorInfo> callback) { 1052 Handle<ExecutableAccessorInfo> callback) {
1055 Register holder_reg = 1053 Register holder_reg = Frontend(receiver(), name);
1056 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
1057
1058 // Stub never generated for non-global objects that require access
1059 // checks.
1060 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1061 1054
1062 __ Push(receiver(), holder_reg); // Receiver. 1055 __ Push(receiver(), holder_reg); // Receiver.
1063 __ li(at, Operand(callback)); // Callback info. 1056 __ li(at, Operand(callback)); // Callback info.
1064 __ push(at); 1057 __ push(at);
1065 __ li(at, Operand(name)); 1058 __ li(at, Operand(name));
1066 __ Push(at, value()); 1059 __ Push(at, value());
1067 1060
1068 // Do tail-call to the runtime system. 1061 // Do tail-call to the runtime system.
1069 ExternalReference store_callback_property = 1062 ExternalReference store_callback_property =
1070 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 1063 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 } 1110 }
1118 __ Ret(); 1111 __ Ret();
1119 } 1112 }
1120 1113
1121 1114
1122 #undef __ 1115 #undef __
1123 #define __ ACCESS_MASM(masm()) 1116 #define __ ACCESS_MASM(masm())
1124 1117
1125 1118
1126 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 1119 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
1127 Handle<JSObject> object, Handle<Name> name) { 1120 Handle<Name> name) {
1128 __ Push(receiver(), this->name(), value()); 1121 __ Push(receiver(), this->name(), value());
1129 1122
1130 // Do tail-call to the runtime system. 1123 // Do tail-call to the runtime system.
1131 ExternalReference store_ic_property = ExternalReference( 1124 ExternalReference store_ic_property = ExternalReference(
1132 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 1125 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
1133 __ TailCallExternalReference(store_ic_property, 3, 1); 1126 __ TailCallExternalReference(store_ic_property, 3, 1);
1134 1127
1135 // Return the generated code. 1128 // Return the generated code.
1136 return GetCode(kind(), Code::FAST, name); 1129 return GetCode(kind(), Code::FAST, name);
1137 } 1130 }
1138 1131
1139 1132
1140 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 1133 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
1141 Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) { 1134 Handle<Name> name) {
1142 NonexistentFrontend(type, last, name); 1135 NonexistentFrontend(name);
1143 1136
1144 // Return undefined if maps of the full prototype chain is still the same. 1137 // Return undefined if maps of the full prototype chain is still the same.
1145 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 1138 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
1146 __ Ret(); 1139 __ Ret();
1147 1140
1148 // Return the generated code. 1141 // Return the generated code.
1149 return GetCode(kind(), Code::FAST, name); 1142 return GetCode(kind(), Code::FAST, name);
1150 } 1143 }
1151 1144
1152 1145
1153 Register* PropertyAccessCompiler::load_calling_convention() { 1146 Register* PropertyAccessCompiler::load_calling_convention() {
1154 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1147 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1155 Register receiver = LoadIC::ReceiverRegister(); 1148 Register receiver = LoadIC::ReceiverRegister();
1156 Register name = LoadIC::NameRegister(); 1149 Register name = LoadIC::NameRegister();
1157 static Register registers[] = { receiver, name, a3, a0, t0, t1 }; 1150 static Register registers[] = { receiver, name, a3, a0, t0, t1 };
1158 return registers; 1151 return registers;
1159 } 1152 }
1160 1153
1161 1154
1162 Register* PropertyAccessCompiler::store_calling_convention() { 1155 Register* PropertyAccessCompiler::store_calling_convention() {
1163 // receiver, name, scratch1, scratch2, scratch3. 1156 // receiver, name, scratch1, scratch2, scratch3.
1164 Register receiver = StoreIC::ReceiverRegister(); 1157 Register receiver = StoreIC::ReceiverRegister();
1165 Register name = StoreIC::NameRegister(); 1158 Register name = StoreIC::NameRegister();
1159 ASSERT(a3.is(KeyedStoreIC::MapRegister()));
1166 static Register registers[] = { receiver, name, a3, t0, t1 }; 1160 static Register registers[] = { receiver, name, a3, t0, t1 };
1167 return registers; 1161 return registers;
1168 } 1162 }
1169 1163
1170 1164
1171 Register* PropertyAccessCompiler::keyed_store_calling_convention() {
1172 // receiver, name, scratch1/map, scratch2, scratch3.
1173 Register receiver = KeyedStoreIC::ReceiverRegister();
1174 Register name = KeyedStoreIC::NameRegister();
1175 Register map = KeyedStoreIC::MapRegister();
1176 static Register registers[] = { receiver, name, map, t0, t1 };
1177 return registers;
1178 }
1179
1180
1181 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } 1165 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
1182 1166
1183 1167
1184 #undef __ 1168 #undef __
1185 #define __ ACCESS_MASM(masm) 1169 #define __ ACCESS_MASM(masm)
1186 1170
1187 1171
1188 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( 1172 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
1189 MacroAssembler* masm, Handle<HeapType> type, Register receiver, 1173 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
1190 Handle<JSFunction> getter) { 1174 Handle<JSFunction> getter) {
(...skipping 28 matching lines...) Expand all
1219 } 1203 }
1220 __ Ret(); 1204 __ Ret();
1221 } 1205 }
1222 1206
1223 1207
1224 #undef __ 1208 #undef __
1225 #define __ ACCESS_MASM(masm()) 1209 #define __ ACCESS_MASM(masm())
1226 1210
1227 1211
1228 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 1212 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
1229 Handle<HeapType> type, Handle<GlobalObject> global,
1230 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) { 1213 Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
1231 Label miss; 1214 Label miss;
1232 1215
1233 FrontendHeader(type, receiver(), global, name, &miss); 1216 FrontendHeader(receiver(), name, &miss);
1234 1217
1235 // Get the value from the cell. 1218 // Get the value from the cell.
1236 __ li(a3, Operand(cell)); 1219 Register result = StoreIC::ValueRegister();
1237 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 1220 __ li(result, Operand(cell));
1221 __ lw(result, FieldMemOperand(result, Cell::kValueOffset));
1238 1222
1239 // Check for deleted property if property can actually be deleted. 1223 // Check for deleted property if property can actually be deleted.
1240 if (!is_dont_delete) { 1224 if (!is_dont_delete) {
1241 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1225 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1242 __ Branch(&miss, eq, t0, Operand(at)); 1226 __ Branch(&miss, eq, result, Operand(at));
1243 } 1227 }
1244 1228
1245 Counters* counters = isolate()->counters(); 1229 Counters* counters = isolate()->counters();
1246 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 1230 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
1247 __ Ret(USE_DELAY_SLOT); 1231 __ Ret(USE_DELAY_SLOT);
1248 __ mov(v0, t0); 1232 __ mov(v0, result);
1249 1233
1250 FrontendFooter(name, &miss); 1234 FrontendFooter(name, &miss);
1251 1235
1252 // Return the generated code. 1236 // Return the generated code.
1253 return GetCode(kind(), Code::NORMAL, name); 1237 return GetCode(kind(), Code::NORMAL, name);
1254 } 1238 }
1255 1239
1256 1240
1257 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, 1241 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
1258 CodeHandleList* handlers, 1242 CodeHandleList* handlers,
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 1369
1386 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1370 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1387 } 1371 }
1388 1372
1389 1373
1390 #undef __ 1374 #undef __
1391 1375
1392 } } // namespace v8::internal 1376 } } // namespace v8::internal
1393 1377
1394 #endif // V8_TARGET_ARCH_MIPS 1378 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/ic-mips.cc ('k') | src/mips64/ic-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698