OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 | 922 |
923 | 923 |
924 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<HeapType> type, | 924 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<HeapType> type, |
925 Register object_reg, | 925 Register object_reg, |
926 Handle<JSObject> holder, | 926 Handle<JSObject> holder, |
927 Handle<Name> name, | 927 Handle<Name> name, |
928 Handle<Object> callback) { | 928 Handle<Object> callback) { |
929 Label miss; | 929 Label miss; |
930 | 930 |
931 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); | 931 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); |
932 | 932 // HandlerFrontendHeader can return its result into scratch1() so do not |
933 // TODO(jbramely): HandlerFrontendHeader returns its result in scratch1(), so | 933 // use it. |
934 // we can't use it below, but that isn't very obvious. Is there a better way | 934 Register scratch2 = this->scratch2(); |
935 // of handling this? | 935 Register scratch3 = this->scratch3(); |
| 936 Register dictionary = this->scratch4(); |
| 937 ASSERT(!AreAliased(reg, scratch2, scratch3, dictionary)); |
936 | 938 |
937 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 939 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
938 ASSERT(!AreAliased(reg, scratch2(), scratch3(), scratch4())); | |
939 | |
940 // Load the properties dictionary. | 940 // Load the properties dictionary. |
941 Register dictionary = scratch4(); | |
942 __ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); | 941 __ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); |
943 | 942 |
944 // Probe the dictionary. | 943 // Probe the dictionary. |
945 Label probe_done; | 944 Label probe_done; |
946 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), | 945 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
947 &miss, | 946 &miss, |
948 &probe_done, | 947 &probe_done, |
949 dictionary, | 948 dictionary, |
950 this->name(), | 949 this->name(), |
951 scratch2(), | 950 scratch2, |
952 scratch3()); | 951 scratch3); |
953 __ Bind(&probe_done); | 952 __ Bind(&probe_done); |
954 | 953 |
955 // If probing finds an entry in the dictionary, scratch3 contains the | 954 // If probing finds an entry in the dictionary, scratch3 contains the |
956 // pointer into the dictionary. Check that the value is the callback. | 955 // pointer into the dictionary. Check that the value is the callback. |
957 Register pointer = scratch3(); | 956 Register pointer = scratch3; |
958 const int kElementsStartOffset = NameDictionary::kHeaderSize + | 957 const int kElementsStartOffset = NameDictionary::kHeaderSize + |
959 NameDictionary::kElementsStartIndex * kPointerSize; | 958 NameDictionary::kElementsStartIndex * kPointerSize; |
960 const int kValueOffset = kElementsStartOffset + kPointerSize; | 959 const int kValueOffset = kElementsStartOffset + kPointerSize; |
961 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); | 960 __ Ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); |
962 __ Cmp(scratch2(), Operand(callback)); | 961 __ Cmp(scratch2, Operand(callback)); |
963 __ B(ne, &miss); | 962 __ B(ne, &miss); |
964 } | 963 } |
965 | 964 |
966 HandlerFrontendFooter(name, &miss); | 965 HandlerFrontendFooter(name, &miss); |
967 return reg; | 966 return reg; |
968 } | 967 } |
969 | 968 |
970 | 969 |
971 void LoadStubCompiler::GenerateLoadField(Register reg, | 970 void LoadStubCompiler::GenerateLoadField(Register reg, |
972 Handle<JSObject> holder, | 971 Handle<JSObject> holder, |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 | 1133 |
1135 ExternalReference ref = | 1134 ExternalReference ref = |
1136 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1135 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
1137 isolate()); | 1136 isolate()); |
1138 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); | 1137 __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); |
1139 } | 1138 } |
1140 } | 1139 } |
1141 | 1140 |
1142 | 1141 |
1143 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 1142 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { |
1144 Label success; | 1143 UseScratchRegisterScope temps(masm()); |
1145 // Check that the object is a boolean. | 1144 // Check that the object is a boolean. |
1146 // TODO(all): Optimize this like LCodeGen::DoDeferredTaggedToI. | 1145 Register true_root = temps.AcquireX(); |
1147 __ JumpIfRoot(object, Heap::kTrueValueRootIndex, &success); | 1146 Register false_root = temps.AcquireX(); |
1148 __ JumpIfNotRoot(object, Heap::kFalseValueRootIndex, miss); | 1147 ASSERT(!AreAliased(object, true_root, false_root)); |
1149 __ Bind(&success); | 1148 __ LoadTrueFalseRoots(true_root, false_root); |
| 1149 __ Cmp(object, true_root); |
| 1150 __ Ccmp(object, false_root, ZFlag, ne); |
| 1151 __ B(ne, miss); |
1150 } | 1152 } |
1151 | 1153 |
1152 | 1154 |
1153 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 1155 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
1154 Handle<JSObject> object, | 1156 Handle<JSObject> object, |
1155 Handle<JSObject> holder, | 1157 Handle<JSObject> holder, |
1156 Handle<Name> name, | 1158 Handle<Name> name, |
1157 Handle<ExecutableAccessorInfo> callback) { | 1159 Handle<ExecutableAccessorInfo> callback) { |
1158 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); | 1160 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); |
1159 Register holder_reg = HandlerFrontend( | 1161 Register holder_reg = HandlerFrontend( |
1160 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 1162 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); |
1161 | 1163 |
1162 // Stub never generated for non-global objects that require access checks. | 1164 // Stub never generated for non-global objects that require access checks. |
1163 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1165 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
1164 | 1166 |
1165 // TODO(jbramley): Make Push take more than four arguments and combine these | 1167 // receiver() and holder_reg can alias. |
1166 // two calls. | 1168 ASSERT(!AreAliased(receiver(), scratch1(), scratch2(), value())); |
1167 __ Push(receiver(), holder_reg); | 1169 ASSERT(!AreAliased(holder_reg, scratch1(), scratch2(), value())); |
1168 __ Mov(scratch1(), Operand(callback)); | 1170 __ Mov(scratch1(), Operand(callback)); |
1169 __ Mov(scratch2(), Operand(name)); | 1171 __ Mov(scratch2(), Operand(name)); |
1170 __ Push(scratch1(), scratch2(), value()); | 1172 __ Push(receiver(), holder_reg, scratch1(), scratch2(), value()); |
1171 | 1173 |
1172 // Do tail-call to the runtime system. | 1174 // Do tail-call to the runtime system. |
1173 ExternalReference store_callback_property = | 1175 ExternalReference store_callback_property = |
1174 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 1176 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
1175 __ TailCallExternalReference(store_callback_property, 5, 1); | 1177 __ TailCallExternalReference(store_callback_property, 5, 1); |
1176 | 1178 |
1177 // Return the generated code. | 1179 // Return the generated code. |
1178 return GetCode(kind(), Code::FAST, name); | 1180 return GetCode(kind(), Code::FAST, name); |
1179 } | 1181 } |
1180 | 1182 |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 | 1488 |
1487 // Miss case, call the runtime. | 1489 // Miss case, call the runtime. |
1488 __ Bind(&miss); | 1490 __ Bind(&miss); |
1489 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1491 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
1490 } | 1492 } |
1491 | 1493 |
1492 | 1494 |
1493 } } // namespace v8::internal | 1495 } } // namespace v8::internal |
1494 | 1496 |
1495 #endif // V8_TARGET_ARCH_A64 | 1497 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |