| 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 |