| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 // Check the prototype chain. | 1059 // Check the prototype chain. |
| 1060 Register reg = CheckPrototypes( | 1060 Register reg = CheckPrototypes( |
| 1061 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1061 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
| 1062 | 1062 |
| 1063 // Get the value from the properties. | 1063 // Get the value from the properties. |
| 1064 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); | 1064 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); |
| 1065 __ ret(0); | 1065 __ ret(0); |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 | 1068 |
| 1069 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1069 void StubCompiler::GenerateDictionaryLoadCallback( |
| 1070 Register name_reg, | 1070 Register receiver, |
| 1071 Register scratch1, | 1071 Register name_reg, |
| 1072 Register scratch2, | 1072 Register scratch1, |
| 1073 Register scratch3, | 1073 Register scratch2, |
| 1074 Handle<AccessorInfo> callback, | 1074 Register scratch3, |
| 1075 Handle<String> name, | 1075 Handle<ExecutableAccessorInfo> callback, |
| 1076 Label* miss) { | 1076 Handle<String> name, |
| 1077 Label* miss) { |
| 1077 ASSERT(!receiver.is(scratch2)); | 1078 ASSERT(!receiver.is(scratch2)); |
| 1078 ASSERT(!receiver.is(scratch3)); | 1079 ASSERT(!receiver.is(scratch3)); |
| 1079 Register dictionary = scratch1; | 1080 Register dictionary = scratch1; |
| 1080 bool must_preserve_dictionary_reg = receiver.is(dictionary); | 1081 bool must_preserve_dictionary_reg = receiver.is(dictionary); |
| 1081 | 1082 |
| 1082 // Load the properties dictionary. | 1083 // Load the properties dictionary. |
| 1083 if (must_preserve_dictionary_reg) { | 1084 if (must_preserve_dictionary_reg) { |
| 1084 __ push(dictionary); | 1085 __ push(dictionary); |
| 1085 } | 1086 } |
| 1086 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 1087 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1111 __ mov(scratch3, | 1112 __ mov(scratch3, |
| 1112 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); | 1113 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); |
| 1113 if (must_preserve_dictionary_reg) { | 1114 if (must_preserve_dictionary_reg) { |
| 1114 __ pop(dictionary); | 1115 __ pop(dictionary); |
| 1115 } | 1116 } |
| 1116 __ cmp(scratch3, callback); | 1117 __ cmp(scratch3, callback); |
| 1117 __ j(not_equal, miss); | 1118 __ j(not_equal, miss); |
| 1118 } | 1119 } |
| 1119 | 1120 |
| 1120 | 1121 |
| 1121 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1122 void StubCompiler::GenerateLoadCallback( |
| 1122 Handle<JSObject> holder, | 1123 Handle<JSObject> object, |
| 1123 Register receiver, | 1124 Handle<JSObject> holder, |
| 1124 Register name_reg, | 1125 Register receiver, |
| 1125 Register scratch1, | 1126 Register name_reg, |
| 1126 Register scratch2, | 1127 Register scratch1, |
| 1127 Register scratch3, | 1128 Register scratch2, |
| 1128 Register scratch4, | 1129 Register scratch3, |
| 1129 Handle<AccessorInfo> callback, | 1130 Register scratch4, |
| 1130 Handle<String> name, | 1131 Handle<ExecutableAccessorInfo> callback, |
| 1131 Label* miss) { | 1132 Handle<String> name, |
| 1133 Label* miss) { |
| 1132 // Check that the receiver isn't a smi. | 1134 // Check that the receiver isn't a smi. |
| 1133 __ JumpIfSmi(receiver, miss); | 1135 __ JumpIfSmi(receiver, miss); |
| 1134 | 1136 |
| 1135 // Check that the maps haven't changed. | 1137 // Check that the maps haven't changed. |
| 1136 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1138 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
| 1137 scratch2, scratch3, name, miss); | 1139 scratch2, scratch3, name, miss); |
| 1138 | 1140 |
| 1139 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1141 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
| 1140 GenerateDictionaryLoadCallback( | 1142 GenerateDictionaryLoadCallback( |
| 1141 reg, name_reg, scratch1, scratch2, scratch3, callback, name, miss); | 1143 reg, name_reg, scratch1, scratch2, scratch3, callback, name, miss); |
| 1142 } | 1144 } |
| 1143 | 1145 |
| 1144 // Insert additional parameters into the stack frame above return address. | 1146 // Insert additional parameters into the stack frame above return address. |
| 1145 ASSERT(!scratch3.is(reg)); | 1147 ASSERT(!scratch3.is(reg)); |
| 1146 __ pop(scratch3); // Get return address to place it below. | 1148 __ pop(scratch3); // Get return address to place it below. |
| 1147 | 1149 |
| 1148 __ push(receiver); // receiver | 1150 __ push(receiver); // receiver |
| 1149 __ mov(scratch2, esp); | 1151 __ mov(scratch2, esp); |
| 1150 ASSERT(!scratch2.is(reg)); | 1152 ASSERT(!scratch2.is(reg)); |
| 1151 __ push(reg); // holder | 1153 __ push(reg); // holder |
| 1152 // Push data from AccessorInfo. | 1154 // Push data from AccessorInfo. |
| 1153 if (isolate()->heap()->InNewSpace(callback->data())) { | 1155 if (isolate()->heap()->InNewSpace(callback->data())) { |
| 1154 __ mov(scratch1, Immediate(callback)); | 1156 __ mov(scratch1, Immediate(callback)); |
| 1155 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); | 1157 __ push(FieldOperand(scratch1, ExecutableAccessorInfo::kDataOffset)); |
| 1156 } else { | 1158 } else { |
| 1157 __ push(Immediate(Handle<Object>(callback->data()))); | 1159 __ push(Immediate(Handle<Object>(callback->data()))); |
| 1158 } | 1160 } |
| 1159 __ push(Immediate(reinterpret_cast<int>(isolate()))); | 1161 __ push(Immediate(reinterpret_cast<int>(isolate()))); |
| 1160 | 1162 |
| 1161 // Save a pointer to where we pushed the arguments pointer. | 1163 // Save a pointer to where we pushed the arguments pointer. |
| 1162 // This will be passed as the const AccessorInfo& to the C++ callback. | 1164 // This will be passed as the const AccessorInfo& to the C++ callback. |
| 1163 __ push(scratch2); | 1165 __ push(scratch2); |
| 1164 | 1166 |
| 1165 __ push(name_reg); // name | 1167 __ push(name_reg); // name |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 __ JumpIfSmi(receiver, miss); | 1227 __ JumpIfSmi(receiver, miss); |
| 1226 | 1228 |
| 1227 // So far the most popular follow ups for interceptor loads are FIELD | 1229 // So far the most popular follow ups for interceptor loads are FIELD |
| 1228 // and CALLBACKS, so inline only them, other cases may be added | 1230 // and CALLBACKS, so inline only them, other cases may be added |
| 1229 // later. | 1231 // later. |
| 1230 bool compile_followup_inline = false; | 1232 bool compile_followup_inline = false; |
| 1231 if (lookup->IsFound() && lookup->IsCacheable()) { | 1233 if (lookup->IsFound() && lookup->IsCacheable()) { |
| 1232 if (lookup->IsField()) { | 1234 if (lookup->IsField()) { |
| 1233 compile_followup_inline = true; | 1235 compile_followup_inline = true; |
| 1234 } else if (lookup->type() == CALLBACKS && | 1236 } else if (lookup->type() == CALLBACKS && |
| 1235 lookup->GetCallbackObject()->IsAccessorInfo()) { | 1237 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { |
| 1236 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1238 ExecutableAccessorInfo* callback = |
| 1239 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); |
| 1237 compile_followup_inline = callback->getter() != NULL && | 1240 compile_followup_inline = callback->getter() != NULL && |
| 1238 callback->IsCompatibleReceiver(*object); | 1241 callback->IsCompatibleReceiver(*object); |
| 1239 } | 1242 } |
| 1240 } | 1243 } |
| 1241 | 1244 |
| 1242 if (compile_followup_inline) { | 1245 if (compile_followup_inline) { |
| 1243 // Compile the interceptor call, followed by inline code to load the | 1246 // Compile the interceptor call, followed by inline code to load the |
| 1244 // property from further up the prototype chain if the call fails. | 1247 // property from further up the prototype chain if the call fails. |
| 1245 // Check that the maps haven't changed. | 1248 // Check that the maps haven't changed. |
| 1246 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 1249 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 // We found FIELD property in prototype chain of interceptor's holder. | 1321 // We found FIELD property in prototype chain of interceptor's holder. |
| 1319 // Retrieve a field from field's holder. | 1322 // Retrieve a field from field's holder. |
| 1320 GenerateFastPropertyLoad(masm(), eax, holder_reg, | 1323 GenerateFastPropertyLoad(masm(), eax, holder_reg, |
| 1321 Handle<JSObject>(lookup->holder()), | 1324 Handle<JSObject>(lookup->holder()), |
| 1322 lookup->GetFieldIndex()); | 1325 lookup->GetFieldIndex()); |
| 1323 __ ret(0); | 1326 __ ret(0); |
| 1324 } else { | 1327 } else { |
| 1325 // We found CALLBACKS property in prototype chain of interceptor's | 1328 // We found CALLBACKS property in prototype chain of interceptor's |
| 1326 // holder. | 1329 // holder. |
| 1327 ASSERT(lookup->type() == CALLBACKS); | 1330 ASSERT(lookup->type() == CALLBACKS); |
| 1328 Handle<AccessorInfo> callback( | 1331 Handle<ExecutableAccessorInfo> callback( |
| 1329 AccessorInfo::cast(lookup->GetCallbackObject())); | 1332 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); |
| 1330 ASSERT(callback->getter() != NULL); | 1333 ASSERT(callback->getter() != NULL); |
| 1331 | 1334 |
| 1332 // Tail call to runtime. | 1335 // Tail call to runtime. |
| 1333 // Important invariant in CALLBACKS case: the code above must be | 1336 // Important invariant in CALLBACKS case: the code above must be |
| 1334 // structured to never clobber |receiver| register. | 1337 // structured to never clobber |receiver| register. |
| 1335 __ pop(scratch2); // return address | 1338 __ pop(scratch2); // return address |
| 1336 __ push(receiver); | 1339 __ push(receiver); |
| 1337 __ push(holder_reg); | 1340 __ push(holder_reg); |
| 1338 __ mov(holder_reg, Immediate(callback)); | 1341 __ mov(holder_reg, Immediate(callback)); |
| 1339 __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset)); | 1342 __ push(FieldOperand(holder_reg, ExecutableAccessorInfo::kDataOffset)); |
| 1340 __ push(Immediate(reinterpret_cast<int>(isolate()))); | 1343 __ push(Immediate(reinterpret_cast<int>(isolate()))); |
| 1341 __ push(holder_reg); | 1344 __ push(holder_reg); |
| 1342 __ push(name_reg); | 1345 __ push(name_reg); |
| 1343 __ push(scratch2); // restore return address | 1346 __ push(scratch2); // restore return address |
| 1344 | 1347 |
| 1345 ExternalReference ref = | 1348 ExternalReference ref = |
| 1346 ExternalReference(IC_Utility(IC::kLoadCallbackProperty), | 1349 ExternalReference(IC_Utility(IC::kLoadCallbackProperty), |
| 1347 masm()->isolate()); | 1350 masm()->isolate()); |
| 1348 __ TailCallExternalReference(ref, 6, 1); | 1351 __ TailCallExternalReference(ref, 6, 1); |
| 1349 } | 1352 } |
| (...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2647 return GetCode(transition.is_null() | 2650 return GetCode(transition.is_null() |
| 2648 ? Code::FIELD | 2651 ? Code::FIELD |
| 2649 : Code::MAP_TRANSITION, name); | 2652 : Code::MAP_TRANSITION, name); |
| 2650 } | 2653 } |
| 2651 | 2654 |
| 2652 | 2655 |
| 2653 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2656 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2654 Handle<String> name, | 2657 Handle<String> name, |
| 2655 Handle<JSObject> receiver, | 2658 Handle<JSObject> receiver, |
| 2656 Handle<JSObject> holder, | 2659 Handle<JSObject> holder, |
| 2657 Handle<AccessorInfo> callback) { | 2660 Handle<ExecutableAccessorInfo> callback) { |
| 2658 // ----------- S t a t e ------------- | 2661 // ----------- S t a t e ------------- |
| 2659 // -- eax : value | 2662 // -- eax : value |
| 2660 // -- ecx : name | 2663 // -- ecx : name |
| 2661 // -- edx : receiver | 2664 // -- edx : receiver |
| 2662 // -- esp[0] : return address | 2665 // -- esp[0] : return address |
| 2663 // ----------------------------------- | 2666 // ----------------------------------- |
| 2664 Label miss; | 2667 Label miss; |
| 2665 // Check that the maps haven't changed, preserving the value register. | 2668 // Check that the maps haven't changed, preserving the value register. |
| 2666 __ push(eax); | 2669 __ push(eax); |
| 2667 __ JumpIfSmi(edx, &miss); | 2670 __ JumpIfSmi(edx, &miss); |
| (...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3917 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3920 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
| 3918 } | 3921 } |
| 3919 } | 3922 } |
| 3920 | 3923 |
| 3921 | 3924 |
| 3922 #undef __ | 3925 #undef __ |
| 3923 | 3926 |
| 3924 } } // namespace v8::internal | 3927 } } // namespace v8::internal |
| 3925 | 3928 |
| 3926 #endif // V8_TARGET_ARCH_IA32 | 3929 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |