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 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 // Check that the maps haven't changed. | 1203 // Check that the maps haven't changed. |
1204 CheckPrototypes( | 1204 CheckPrototypes( |
1205 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1205 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1206 | 1206 |
1207 // Return the constant value. | 1207 // Return the constant value. |
1208 __ LoadHeapObject(r0, value); | 1208 __ LoadHeapObject(r0, value); |
1209 __ Ret(); | 1209 __ Ret(); |
1210 } | 1210 } |
1211 | 1211 |
1212 | 1212 |
1213 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1213 void StubCompiler::GenerateDictionaryLoadCallback( |
1214 Register name_reg, | 1214 Register receiver, |
1215 Register scratch1, | 1215 Register name_reg, |
1216 Register scratch2, | 1216 Register scratch1, |
1217 Register scratch3, | 1217 Register scratch2, |
1218 Handle<AccessorInfo> callback, | 1218 Register scratch3, |
1219 Handle<String> name, | 1219 Handle<ExecutableAccessorInfo> callback, |
1220 Label* miss) { | 1220 Handle<String> name, |
| 1221 Label* miss) { |
1221 ASSERT(!receiver.is(scratch1)); | 1222 ASSERT(!receiver.is(scratch1)); |
1222 ASSERT(!receiver.is(scratch2)); | 1223 ASSERT(!receiver.is(scratch2)); |
1223 ASSERT(!receiver.is(scratch3)); | 1224 ASSERT(!receiver.is(scratch3)); |
1224 | 1225 |
1225 // Load the properties dictionary. | 1226 // Load the properties dictionary. |
1226 Register dictionary = scratch1; | 1227 Register dictionary = scratch1; |
1227 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 1228 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
1228 | 1229 |
1229 // Probe the dictionary. | 1230 // Probe the dictionary. |
1230 Label probe_done; | 1231 Label probe_done; |
(...skipping 11 matching lines...) Expand all Loading... |
1242 Register pointer = scratch3; | 1243 Register pointer = scratch3; |
1243 const int kElementsStartOffset = StringDictionary::kHeaderSize + | 1244 const int kElementsStartOffset = StringDictionary::kHeaderSize + |
1244 StringDictionary::kElementsStartIndex * kPointerSize; | 1245 StringDictionary::kElementsStartIndex * kPointerSize; |
1245 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1246 const int kValueOffset = kElementsStartOffset + kPointerSize; |
1246 __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); | 1247 __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); |
1247 __ cmp(scratch2, Operand(callback)); | 1248 __ cmp(scratch2, Operand(callback)); |
1248 __ b(ne, miss); | 1249 __ b(ne, miss); |
1249 } | 1250 } |
1250 | 1251 |
1251 | 1252 |
1252 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1253 void StubCompiler::GenerateLoadCallback( |
1253 Handle<JSObject> holder, | 1254 Handle<JSObject> object, |
1254 Register receiver, | 1255 Handle<JSObject> holder, |
1255 Register name_reg, | 1256 Register receiver, |
1256 Register scratch1, | 1257 Register name_reg, |
1257 Register scratch2, | 1258 Register scratch1, |
1258 Register scratch3, | 1259 Register scratch2, |
1259 Register scratch4, | 1260 Register scratch3, |
1260 Handle<AccessorInfo> callback, | 1261 Register scratch4, |
1261 Handle<String> name, | 1262 Handle<ExecutableAccessorInfo> callback, |
1262 Label* miss) { | 1263 Handle<String> name, |
| 1264 Label* miss) { |
1263 // Check that the receiver isn't a smi. | 1265 // Check that the receiver isn't a smi. |
1264 __ JumpIfSmi(receiver, miss); | 1266 __ JumpIfSmi(receiver, miss); |
1265 | 1267 |
1266 // Check that the maps haven't changed. | 1268 // Check that the maps haven't changed. |
1267 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1269 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
1268 scratch2, scratch3, name, miss); | 1270 scratch2, scratch3, name, miss); |
1269 | 1271 |
1270 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1272 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
1271 GenerateDictionaryLoadCallback( | 1273 GenerateDictionaryLoadCallback( |
1272 reg, name_reg, scratch2, scratch3, scratch4, callback, name, miss); | 1274 reg, name_reg, scratch2, scratch3, scratch4, callback, name, miss); |
1273 } | 1275 } |
1274 | 1276 |
1275 // Build AccessorInfo::args_ list on the stack and push property name below | 1277 // Build AccessorInfo::args_ list on the stack and push property name below |
1276 // the exit frame to make GC aware of them and store pointers to them. | 1278 // the exit frame to make GC aware of them and store pointers to them. |
1277 __ push(receiver); | 1279 __ push(receiver); |
1278 __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_ | 1280 __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_ |
1279 if (heap()->InNewSpace(callback->data())) { | 1281 if (heap()->InNewSpace(callback->data())) { |
1280 __ Move(scratch3, callback); | 1282 __ Move(scratch3, callback); |
1281 __ ldr(scratch3, FieldMemOperand(scratch3, AccessorInfo::kDataOffset)); | 1283 __ ldr(scratch3, |
| 1284 FieldMemOperand(scratch3, ExecutableAccessorInfo::kDataOffset)); |
1282 } else { | 1285 } else { |
1283 __ Move(scratch3, Handle<Object>(callback->data())); | 1286 __ Move(scratch3, Handle<Object>(callback->data())); |
1284 } | 1287 } |
1285 __ Push(reg, scratch3); | 1288 __ Push(reg, scratch3); |
1286 __ mov(scratch3, Operand(ExternalReference::isolate_address())); | 1289 __ mov(scratch3, Operand(ExternalReference::isolate_address())); |
1287 __ Push(scratch3, name_reg); | 1290 __ Push(scratch3, name_reg); |
1288 __ mov(r0, sp); // r0 = Handle<String> | 1291 __ mov(r0, sp); // r0 = Handle<String> |
1289 | 1292 |
1290 const int kApiStackSpace = 1; | 1293 const int kApiStackSpace = 1; |
1291 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1294 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 __ JumpIfSmi(receiver, miss); | 1327 __ JumpIfSmi(receiver, miss); |
1325 | 1328 |
1326 // So far the most popular follow ups for interceptor loads are FIELD | 1329 // So far the most popular follow ups for interceptor loads are FIELD |
1327 // and CALLBACKS, so inline only them, other cases may be added | 1330 // and CALLBACKS, so inline only them, other cases may be added |
1328 // later. | 1331 // later. |
1329 bool compile_followup_inline = false; | 1332 bool compile_followup_inline = false; |
1330 if (lookup->IsFound() && lookup->IsCacheable()) { | 1333 if (lookup->IsFound() && lookup->IsCacheable()) { |
1331 if (lookup->IsField()) { | 1334 if (lookup->IsField()) { |
1332 compile_followup_inline = true; | 1335 compile_followup_inline = true; |
1333 } else if (lookup->type() == CALLBACKS && | 1336 } else if (lookup->type() == CALLBACKS && |
1334 lookup->GetCallbackObject()->IsAccessorInfo()) { | 1337 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { |
1335 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1338 ExecutableAccessorInfo* callback = |
| 1339 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); |
1336 compile_followup_inline = callback->getter() != NULL && | 1340 compile_followup_inline = callback->getter() != NULL && |
1337 callback->IsCompatibleReceiver(*object); | 1341 callback->IsCompatibleReceiver(*object); |
1338 } | 1342 } |
1339 } | 1343 } |
1340 | 1344 |
1341 if (compile_followup_inline) { | 1345 if (compile_followup_inline) { |
1342 // Compile the interceptor call, followed by inline code to load the | 1346 // Compile the interceptor call, followed by inline code to load the |
1343 // property from further up the prototype chain if the call fails. | 1347 // property from further up the prototype chain if the call fails. |
1344 // Check that the maps haven't changed. | 1348 // Check that the maps haven't changed. |
1345 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 1349 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 // We found FIELD property in prototype chain of interceptor's holder. | 1410 // We found FIELD property in prototype chain of interceptor's holder. |
1407 // Retrieve a field from field's holder. | 1411 // Retrieve a field from field's holder. |
1408 GenerateFastPropertyLoad(masm(), r0, holder_reg, | 1412 GenerateFastPropertyLoad(masm(), r0, holder_reg, |
1409 Handle<JSObject>(lookup->holder()), | 1413 Handle<JSObject>(lookup->holder()), |
1410 lookup->GetFieldIndex()); | 1414 lookup->GetFieldIndex()); |
1411 __ Ret(); | 1415 __ Ret(); |
1412 } else { | 1416 } else { |
1413 // We found CALLBACKS property in prototype chain of interceptor's | 1417 // We found CALLBACKS property in prototype chain of interceptor's |
1414 // holder. | 1418 // holder. |
1415 ASSERT(lookup->type() == CALLBACKS); | 1419 ASSERT(lookup->type() == CALLBACKS); |
1416 Handle<AccessorInfo> callback( | 1420 Handle<ExecutableAccessorInfo> callback( |
1417 AccessorInfo::cast(lookup->GetCallbackObject())); | 1421 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); |
1418 ASSERT(callback->getter() != NULL); | 1422 ASSERT(callback->getter() != NULL); |
1419 | 1423 |
1420 // Tail call to runtime. | 1424 // Tail call to runtime. |
1421 // Important invariant in CALLBACKS case: the code above must be | 1425 // Important invariant in CALLBACKS case: the code above must be |
1422 // structured to never clobber |receiver| register. | 1426 // structured to never clobber |receiver| register. |
1423 __ Move(scratch2, callback); | 1427 __ Move(scratch2, callback); |
1424 // holder_reg is either receiver or scratch1. | 1428 // holder_reg is either receiver or scratch1. |
1425 if (!receiver.is(holder_reg)) { | 1429 if (!receiver.is(holder_reg)) { |
1426 ASSERT(scratch1.is(holder_reg)); | 1430 ASSERT(scratch1.is(holder_reg)); |
1427 __ Push(receiver, holder_reg); | 1431 __ Push(receiver, holder_reg); |
1428 } else { | 1432 } else { |
1429 __ push(receiver); | 1433 __ push(receiver); |
1430 __ push(holder_reg); | 1434 __ push(holder_reg); |
1431 } | 1435 } |
1432 __ ldr(scratch3, | 1436 __ ldr(scratch3, |
1433 FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); | 1437 FieldMemOperand(scratch2, ExecutableAccessorInfo::kDataOffset)); |
1434 __ mov(scratch1, Operand(ExternalReference::isolate_address())); | 1438 __ mov(scratch1, Operand(ExternalReference::isolate_address())); |
1435 __ Push(scratch3, scratch1, scratch2, name_reg); | 1439 __ Push(scratch3, scratch1, scratch2, name_reg); |
1436 | 1440 |
1437 ExternalReference ref = | 1441 ExternalReference ref = |
1438 ExternalReference(IC_Utility(IC::kLoadCallbackProperty), | 1442 ExternalReference(IC_Utility(IC::kLoadCallbackProperty), |
1439 masm()->isolate()); | 1443 masm()->isolate()); |
1440 __ TailCallExternalReference(ref, 6, 1); | 1444 __ TailCallExternalReference(ref, 6, 1); |
1441 } | 1445 } |
1442 } else { // !compile_followup_inline | 1446 } else { // !compile_followup_inline |
1443 // Call the runtime system to load the interceptor. | 1447 // Call the runtime system to load the interceptor. |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2688 return GetCode(transition.is_null() | 2692 return GetCode(transition.is_null() |
2689 ? Code::FIELD | 2693 ? Code::FIELD |
2690 : Code::MAP_TRANSITION, name); | 2694 : Code::MAP_TRANSITION, name); |
2691 } | 2695 } |
2692 | 2696 |
2693 | 2697 |
2694 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2698 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2695 Handle<String> name, | 2699 Handle<String> name, |
2696 Handle<JSObject> receiver, | 2700 Handle<JSObject> receiver, |
2697 Handle<JSObject> holder, | 2701 Handle<JSObject> holder, |
2698 Handle<AccessorInfo> callback) { | 2702 Handle<ExecutableAccessorInfo> callback) { |
2699 // ----------- S t a t e ------------- | 2703 // ----------- S t a t e ------------- |
2700 // -- r0 : value | 2704 // -- r0 : value |
2701 // -- r1 : receiver | 2705 // -- r1 : receiver |
2702 // -- r2 : name | 2706 // -- r2 : name |
2703 // -- lr : return address | 2707 // -- lr : return address |
2704 // ----------------------------------- | 2708 // ----------------------------------- |
2705 Label miss; | 2709 Label miss; |
2706 // Check that the maps haven't changed. | 2710 // Check that the maps haven't changed. |
2707 __ JumpIfSmi(r1, &miss); | 2711 __ JumpIfSmi(r1, &miss); |
2708 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); | 2712 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); |
(...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4165 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4169 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4166 } | 4170 } |
4167 } | 4171 } |
4168 | 4172 |
4169 | 4173 |
4170 #undef __ | 4174 #undef __ |
4171 | 4175 |
4172 } } // namespace v8::internal | 4176 } } // namespace v8::internal |
4173 | 4177 |
4174 #endif // V8_TARGET_ARCH_ARM | 4178 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |