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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 HandleScope scope(isolate()); | 153 HandleScope scope(isolate()); |
154 // Compute the JavaScript frame for the frame pointer of this IC | 154 // Compute the JavaScript frame for the frame pointer of this IC |
155 // structure. We need this to be able to find the function | 155 // structure. We need this to be able to find the function |
156 // corresponding to the frame. | 156 // corresponding to the frame. |
157 StackFrameIterator it(isolate()); | 157 StackFrameIterator it(isolate()); |
158 while (it.frame()->fp() != this->fp()) it.Advance(); | 158 while (it.frame()->fp() != this->fp()) it.Advance(); |
159 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); | 159 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); |
160 // Find the function on the stack and both the active code for the | 160 // Find the function on the stack and both the active code for the |
161 // function and the original code. | 161 // function and the original code. |
162 JSFunction* function = JSFunction::cast(frame->function()); | 162 JSFunction* function = JSFunction::cast(frame->function()); |
163 Handle<SharedFunctionInfo> shared(function->shared()); | 163 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); |
164 Code* code = shared->code(); | 164 Code* code = shared->code(); |
165 ASSERT(Debug::HasDebugInfo(shared)); | 165 ASSERT(Debug::HasDebugInfo(shared)); |
166 Code* original_code = Debug::GetDebugInfo(shared)->original_code(); | 166 Code* original_code = Debug::GetDebugInfo(shared)->original_code(); |
167 ASSERT(original_code->IsCode()); | 167 ASSERT(original_code->IsCode()); |
168 // Get the address of the call site in the active code. This is the | 168 // Get the address of the call site in the active code. This is the |
169 // place where the call to DebugBreakXXX is and where the IC | 169 // place where the call to DebugBreakXXX is and where the IC |
170 // normally would be. | 170 // normally would be. |
171 Address addr = Assembler::target_address_from_return_address(pc()); | 171 Address addr = Assembler::target_address_from_return_address(pc()); |
172 // Return the address in the original code. This is the place where | 172 // Return the address in the original code. This is the place where |
173 // the call which has been overwritten by the DebugBreakXXX resides | 173 // the call which has been overwritten by the DebugBreakXXX resides |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 // without actual getter. | 428 // without actual getter. |
429 while (true) { | 429 while (true) { |
430 object->Lookup(*name, lookup); | 430 object->Lookup(*name, lookup); |
431 // Besides normal conditions (property not found or it's not | 431 // Besides normal conditions (property not found or it's not |
432 // an interceptor), bail out if lookup is not cacheable: we won't | 432 // an interceptor), bail out if lookup is not cacheable: we won't |
433 // be able to IC it anyway and regular lookup should work fine. | 433 // be able to IC it anyway and regular lookup should work fine. |
434 if (!lookup->IsInterceptor() || !lookup->IsCacheable()) { | 434 if (!lookup->IsInterceptor() || !lookup->IsCacheable()) { |
435 return; | 435 return; |
436 } | 436 } |
437 | 437 |
438 Handle<JSObject> holder(lookup->holder()); | 438 Handle<JSObject> holder(lookup->holder(), lookup->isolate()); |
439 if (HasInterceptorGetter(*holder)) { | 439 if (HasInterceptorGetter(*holder)) { |
440 return; | 440 return; |
441 } | 441 } |
442 | 442 |
443 holder->LocalLookupRealNamedProperty(*name, lookup); | 443 holder->LocalLookupRealNamedProperty(*name, lookup); |
444 if (lookup->IsFound()) { | 444 if (lookup->IsFound()) { |
445 ASSERT(!lookup->IsInterceptor()); | 445 ASSERT(!lookup->IsInterceptor()); |
446 return; | 446 return; |
447 } | 447 } |
448 | 448 |
449 Handle<Object> proto(holder->GetPrototype(), name->GetIsolate()); | 449 Handle<Object> proto(holder->GetPrototype(), lookup->isolate()); |
450 if (proto->IsNull()) { | 450 if (proto->IsNull()) { |
451 ASSERT(!lookup->IsFound()); | 451 ASSERT(!lookup->IsFound()); |
452 return; | 452 return; |
453 } | 453 } |
454 | 454 |
455 object = proto; | 455 object = proto; |
456 } | 456 } |
457 } | 457 } |
458 | 458 |
459 | 459 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 return false; | 629 return false; |
630 } | 630 } |
631 | 631 |
632 | 632 |
633 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, | 633 Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, |
634 State state, | 634 State state, |
635 Code::ExtraICState extra_state, | 635 Code::ExtraICState extra_state, |
636 Handle<Object> object, | 636 Handle<Object> object, |
637 Handle<String> name) { | 637 Handle<String> name) { |
638 int argc = target()->arguments_count(); | 638 int argc = target()->arguments_count(); |
639 Handle<JSObject> holder(lookup->holder()); | 639 Handle<JSObject> holder(lookup->holder(), isolate()); |
640 switch (lookup->type()) { | 640 switch (lookup->type()) { |
641 case FIELD: { | 641 case FIELD: { |
642 PropertyIndex index = lookup->GetFieldIndex(); | 642 PropertyIndex index = lookup->GetFieldIndex(); |
643 return isolate()->stub_cache()->ComputeCallField( | 643 return isolate()->stub_cache()->ComputeCallField( |
644 argc, kind_, extra_state, name, object, holder, index); | 644 argc, kind_, extra_state, name, object, holder, index); |
645 } | 645 } |
646 case CONSTANT_FUNCTION: { | 646 case CONSTANT_FUNCTION: { |
647 // Get the constant function and compute the code stub for this | 647 // Get the constant function and compute the code stub for this |
648 // call; used for rewriting to monomorphic state and making sure | 648 // call; used for rewriting to monomorphic state and making sure |
649 // that the code stub is in the stub cache. | 649 // that the code stub is in the stub cache. |
650 Handle<JSFunction> function(lookup->GetConstantFunction()); | 650 Handle<JSFunction> function(lookup->GetConstantFunction(), isolate()); |
651 return isolate()->stub_cache()->ComputeCallConstant( | 651 return isolate()->stub_cache()->ComputeCallConstant( |
652 argc, kind_, extra_state, name, object, holder, function); | 652 argc, kind_, extra_state, name, object, holder, function); |
653 } | 653 } |
654 case NORMAL: { | 654 case NORMAL: { |
655 // If we return a null handle, the IC will not be patched. | 655 // If we return a null handle, the IC will not be patched. |
656 if (!object->IsJSObject()) return Handle<Code>::null(); | 656 if (!object->IsJSObject()) return Handle<Code>::null(); |
657 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 657 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
658 | 658 |
659 if (holder->IsGlobalObject()) { | 659 if (holder->IsGlobalObject()) { |
660 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 660 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
661 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); | 661 Handle<JSGlobalPropertyCell> cell( |
| 662 global->GetPropertyCell(lookup), isolate()); |
662 if (!cell->value()->IsJSFunction()) return Handle<Code>::null(); | 663 if (!cell->value()->IsJSFunction()) return Handle<Code>::null(); |
663 Handle<JSFunction> function(JSFunction::cast(cell->value())); | 664 Handle<JSFunction> function(JSFunction::cast(cell->value())); |
664 return isolate()->stub_cache()->ComputeCallGlobal( | 665 return isolate()->stub_cache()->ComputeCallGlobal( |
665 argc, kind_, extra_state, name, receiver, global, cell, function); | 666 argc, kind_, extra_state, name, receiver, global, cell, function); |
666 } else { | 667 } else { |
667 // There is only one shared stub for calling normalized | 668 // There is only one shared stub for calling normalized |
668 // properties. It does not traverse the prototype chain, so the | 669 // properties. It does not traverse the prototype chain, so the |
669 // property must be found in the receiver for the stub to be | 670 // property must be found in the receiver for the stub to be |
670 // applicable. | 671 // applicable. |
671 if (!holder.is_identical_to(receiver)) return Handle<Code>::null(); | 672 if (!holder.is_identical_to(receiver)) return Handle<Code>::null(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 UpdateMegamorphicCache(map, *name, target()); | 740 UpdateMegamorphicCache(map, *name, target()); |
740 } | 741 } |
741 } | 742 } |
742 set_target(*code); | 743 set_target(*code); |
743 break; | 744 break; |
744 case MEGAMORPHIC: { | 745 case MEGAMORPHIC: { |
745 // Cache code holding map should be consistent with | 746 // Cache code holding map should be consistent with |
746 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. | 747 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. |
747 Handle<JSObject> cache_object = object->IsJSObject() | 748 Handle<JSObject> cache_object = object->IsJSObject() |
748 ? Handle<JSObject>::cast(object) | 749 ? Handle<JSObject>::cast(object) |
749 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))); | 750 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), |
| 751 isolate()); |
750 // Update the stub cache. | 752 // Update the stub cache. |
751 UpdateMegamorphicCache(cache_object->map(), *name, *code); | 753 UpdateMegamorphicCache(cache_object->map(), *name, *code); |
752 break; | 754 break; |
753 } | 755 } |
754 case DEBUG_STUB: | 756 case DEBUG_STUB: |
755 break; | 757 break; |
756 case POLYMORPHIC: | 758 case POLYMORPHIC: |
757 case GENERIC: | 759 case GENERIC: |
758 UNREACHABLE(); | 760 UNREACHABLE(); |
759 break; | 761 break; |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 return isolate()->stub_cache()->ComputeLoadField( | 1191 return isolate()->stub_cache()->ComputeLoadField( |
1190 name, receiver, holder, lookup->GetFieldIndex()); | 1192 name, receiver, holder, lookup->GetFieldIndex()); |
1191 case CONSTANT_FUNCTION: { | 1193 case CONSTANT_FUNCTION: { |
1192 Handle<JSFunction> constant(lookup->GetConstantFunction()); | 1194 Handle<JSFunction> constant(lookup->GetConstantFunction()); |
1193 return isolate()->stub_cache()->ComputeLoadConstant( | 1195 return isolate()->stub_cache()->ComputeLoadConstant( |
1194 name, receiver, holder, constant); | 1196 name, receiver, holder, constant); |
1195 } | 1197 } |
1196 case NORMAL: | 1198 case NORMAL: |
1197 if (holder->IsGlobalObject()) { | 1199 if (holder->IsGlobalObject()) { |
1198 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 1200 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
1199 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); | 1201 Handle<JSGlobalPropertyCell> cell( |
| 1202 global->GetPropertyCell(lookup), isolate()); |
1200 return isolate()->stub_cache()->ComputeLoadGlobal( | 1203 return isolate()->stub_cache()->ComputeLoadGlobal( |
1201 name, receiver, global, cell, lookup->IsDontDelete()); | 1204 name, receiver, global, cell, lookup->IsDontDelete()); |
1202 } | 1205 } |
1203 // There is only one shared stub for loading normalized | 1206 // There is only one shared stub for loading normalized |
1204 // properties. It does not traverse the prototype chain, so the | 1207 // properties. It does not traverse the prototype chain, so the |
1205 // property must be found in the receiver for the stub to be | 1208 // property must be found in the receiver for the stub to be |
1206 // applicable. | 1209 // applicable. |
1207 if (!holder.is_identical_to(receiver)) break; | 1210 if (!holder.is_identical_to(receiver)) break; |
1208 return isolate()->stub_cache()->ComputeLoadNormal(name, receiver); | 1211 return isolate()->stub_cache()->ComputeLoadNormal(name, receiver); |
1209 case CALLBACKS: { | 1212 case CALLBACKS: { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 State ic_state = target()->ic_state(); | 1268 State ic_state = target()->ic_state(); |
1266 | 1269 |
1267 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 1270 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
1268 // via megamorphic stubs, since they don't have a map in their relocation info | 1271 // via megamorphic stubs, since they don't have a map in their relocation info |
1269 // and so the stubs can't be harvested for the object needed for a map check. | 1272 // and so the stubs can't be harvested for the object needed for a map check. |
1270 if (target()->type() != Code::NORMAL) { | 1273 if (target()->type() != Code::NORMAL) { |
1271 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); | 1274 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); |
1272 return generic_stub(); | 1275 return generic_stub(); |
1273 } | 1276 } |
1274 | 1277 |
1275 Handle<Map> receiver_map(receiver->map()); | 1278 Handle<Map> receiver_map(receiver->map(), isolate()); |
1276 MapHandleList target_receiver_maps; | 1279 MapHandleList target_receiver_maps; |
1277 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | 1280 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
1278 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1281 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
1279 // yet will do so and stay there. | 1282 // yet will do so and stay there. |
1280 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); | 1283 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); |
1281 } | 1284 } |
1282 | 1285 |
1283 if (target() == *string_stub()) { | 1286 if (target() == *string_stub()) { |
1284 target_receiver_maps.Add(isolate()->factory()->string_map()); | 1287 target_receiver_maps.Add(isolate()->factory()->string_map()); |
1285 } else { | 1288 } else { |
1286 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); | 1289 GetReceiverMapsForStub(Handle<Code>(target(), isolate()), |
| 1290 &target_receiver_maps); |
1287 if (target_receiver_maps.length() == 0) { | 1291 if (target_receiver_maps.length() == 0) { |
1288 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); | 1292 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); |
1289 } | 1293 } |
1290 } | 1294 } |
1291 | 1295 |
1292 // The first time a receiver is seen that is a transitioned version of the | 1296 // The first time a receiver is seen that is a transitioned version of the |
1293 // previous monomorphic receiver type, assume the new ElementsKind is the | 1297 // previous monomorphic receiver type, assume the new ElementsKind is the |
1294 // monomorphic type. This benefits global arrays that only transition | 1298 // monomorphic type. This benefits global arrays that only transition |
1295 // once, and all call sites accessing them are faster if they remain | 1299 // once, and all call sites accessing them are faster if they remain |
1296 // monomorphic. If this optimistic assumption is not true, the IC will | 1300 // monomorphic. If this optimistic assumption is not true, the IC will |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 } | 1376 } |
1373 | 1377 |
1374 | 1378 |
1375 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, | 1379 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, |
1376 Handle<JSObject> receiver, | 1380 Handle<JSObject> receiver, |
1377 Handle<String> name) { | 1381 Handle<String> name) { |
1378 // Bail out if we didn't find a result. | 1382 // Bail out if we didn't find a result. |
1379 if (!lookup->IsProperty()) return Handle<Code>::null(); | 1383 if (!lookup->IsProperty()) return Handle<Code>::null(); |
1380 | 1384 |
1381 // Compute a monomorphic stub. | 1385 // Compute a monomorphic stub. |
1382 Handle<JSObject> holder(lookup->holder()); | 1386 Handle<JSObject> holder(lookup->holder(), isolate()); |
1383 switch (lookup->type()) { | 1387 switch (lookup->type()) { |
1384 case FIELD: | 1388 case FIELD: |
1385 return isolate()->stub_cache()->ComputeKeyedLoadField( | 1389 return isolate()->stub_cache()->ComputeKeyedLoadField( |
1386 name, receiver, holder, lookup->GetFieldIndex()); | 1390 name, receiver, holder, lookup->GetFieldIndex()); |
1387 case CONSTANT_FUNCTION: { | 1391 case CONSTANT_FUNCTION: { |
1388 Handle<JSFunction> constant(lookup->GetConstantFunction()); | 1392 Handle<JSFunction> constant(lookup->GetConstantFunction(), isolate()); |
1389 return isolate()->stub_cache()->ComputeKeyedLoadConstant( | 1393 return isolate()->stub_cache()->ComputeKeyedLoadConstant( |
1390 name, receiver, holder, constant); | 1394 name, receiver, holder, constant); |
1391 } | 1395 } |
1392 case CALLBACKS: { | 1396 case CALLBACKS: { |
1393 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate()); | 1397 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate()); |
1394 // TODO(dcarney): Handle DeclaredAccessorInfo correctly. | 1398 // TODO(dcarney): Handle DeclaredAccessorInfo correctly. |
1395 if (!callback_object->IsExecutableAccessorInfo()) break; | 1399 if (!callback_object->IsExecutableAccessorInfo()) break; |
1396 Handle<ExecutableAccessorInfo> callback = | 1400 Handle<ExecutableAccessorInfo> callback = |
1397 Handle<ExecutableAccessorInfo>::cast(callback_object); | 1401 Handle<ExecutableAccessorInfo>::cast(callback_object); |
1398 if (v8::ToCData<Address>(callback->getter()) == 0) break; | 1402 if (v8::ToCData<Address>(callback->getter()) == 0) break; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 case FIELD: | 1575 case FIELD: |
1572 return isolate()->stub_cache()->ComputeStoreField( | 1576 return isolate()->stub_cache()->ComputeStoreField( |
1573 name, receiver, lookup->GetFieldIndex().field_index(), | 1577 name, receiver, lookup->GetFieldIndex().field_index(), |
1574 Handle<Map>::null(), strict_mode); | 1578 Handle<Map>::null(), strict_mode); |
1575 case NORMAL: | 1579 case NORMAL: |
1576 if (receiver->IsGlobalObject()) { | 1580 if (receiver->IsGlobalObject()) { |
1577 // The stub generated for the global object picks the value directly | 1581 // The stub generated for the global object picks the value directly |
1578 // from the property cell. So the property must be directly on the | 1582 // from the property cell. So the property must be directly on the |
1579 // global object. | 1583 // global object. |
1580 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); | 1584 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); |
1581 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); | 1585 Handle<JSGlobalPropertyCell> cell( |
| 1586 global->GetPropertyCell(lookup), isolate()); |
1582 return isolate()->stub_cache()->ComputeStoreGlobal( | 1587 return isolate()->stub_cache()->ComputeStoreGlobal( |
1583 name, global, cell, strict_mode); | 1588 name, global, cell, strict_mode); |
1584 } | 1589 } |
1585 if (!holder.is_identical_to(receiver)) break; | 1590 if (!holder.is_identical_to(receiver)) break; |
1586 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); | 1591 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); |
1587 case CALLBACKS: { | 1592 case CALLBACKS: { |
1588 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 1593 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
1589 if (callback->IsExecutableAccessorInfo()) { | 1594 if (callback->IsExecutableAccessorInfo()) { |
1590 Handle<ExecutableAccessorInfo> info = | 1595 Handle<ExecutableAccessorInfo> info = |
1591 Handle<ExecutableAccessorInfo>::cast(callback); | 1596 Handle<ExecutableAccessorInfo>::cast(callback); |
1592 if (v8::ToCData<Address>(info->setter()) == 0) break; | 1597 if (v8::ToCData<Address>(info->setter()) == 0) break; |
1593 if (!holder->HasFastProperties()) break; | 1598 if (!holder->HasFastProperties()) break; |
1594 if (!info->IsCompatibleReceiver(*receiver)) break; | 1599 if (!info->IsCompatibleReceiver(*receiver)) break; |
1595 return isolate()->stub_cache()->ComputeStoreCallback( | 1600 return isolate()->stub_cache()->ComputeStoreCallback( |
1596 name, receiver, holder, info, strict_mode); | 1601 name, receiver, holder, info, strict_mode); |
1597 } else if (callback->IsAccessorPair()) { | 1602 } else if (callback->IsAccessorPair()) { |
1598 Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter(), | 1603 Handle<Object> setter( |
1599 isolate()); | 1604 Handle<AccessorPair>::cast(callback)->setter(), isolate()); |
1600 if (!setter->IsJSFunction()) break; | 1605 if (!setter->IsJSFunction()) break; |
1601 if (holder->IsGlobalObject()) break; | 1606 if (holder->IsGlobalObject()) break; |
1602 if (!holder->HasFastProperties()) break; | 1607 if (!holder->HasFastProperties()) break; |
1603 return isolate()->stub_cache()->ComputeStoreViaSetter( | 1608 return isolate()->stub_cache()->ComputeStoreViaSetter( |
1604 name, receiver, holder, Handle<JSFunction>::cast(setter), | 1609 name, receiver, holder, Handle<JSFunction>::cast(setter), |
1605 strict_mode); | 1610 strict_mode); |
1606 } | 1611 } |
1607 // TODO(dcarney): Handle correctly. | 1612 // TODO(dcarney): Handle correctly. |
1608 if (callback->IsDeclaredAccessorInfo()) break; | 1613 if (callback->IsDeclaredAccessorInfo()) break; |
1609 ASSERT(callback->IsForeign()); | 1614 ASSERT(callback->IsForeign()); |
1610 // No IC support for old-style native accessors. | 1615 // No IC support for old-style native accessors. |
1611 break; | 1616 break; |
1612 } | 1617 } |
1613 case INTERCEPTOR: | 1618 case INTERCEPTOR: |
1614 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); | 1619 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); |
1615 return isolate()->stub_cache()->ComputeStoreInterceptor( | 1620 return isolate()->stub_cache()->ComputeStoreInterceptor( |
1616 name, receiver, strict_mode); | 1621 name, receiver, strict_mode); |
1617 case CONSTANT_FUNCTION: | 1622 case CONSTANT_FUNCTION: |
1618 break; | 1623 break; |
1619 case TRANSITION: { | 1624 case TRANSITION: { |
1620 Handle<Map> transition(lookup->GetTransitionTarget()); | 1625 Handle<Map> transition(lookup->GetTransitionTarget(), isolate()); |
1621 int descriptor = transition->LastAdded(); | 1626 int descriptor = transition->LastAdded(); |
1622 | 1627 |
1623 DescriptorArray* target_descriptors = transition->instance_descriptors(); | 1628 DescriptorArray* target_descriptors = transition->instance_descriptors(); |
1624 PropertyDetails details = target_descriptors->GetDetails(descriptor); | 1629 PropertyDetails details = target_descriptors->GetDetails(descriptor); |
1625 | 1630 |
1626 if (details.type() != FIELD || details.attributes() != NONE) break; | 1631 if (details.type() != FIELD || details.attributes() != NONE) break; |
1627 | 1632 |
1628 int field_index = target_descriptors->GetFieldIndex(descriptor); | 1633 int field_index = target_descriptors->GetFieldIndex(descriptor); |
1629 return isolate()->stub_cache()->ComputeStoreField( | 1634 return isolate()->stub_cache()->ComputeStoreField( |
1630 name, receiver, field_index, transition, strict_mode); | 1635 name, receiver, field_index, transition, strict_mode); |
(...skipping 23 matching lines...) Expand all Loading... |
1654 // TODO(danno): We'll soon handle MONOMORPHIC ICs that also support | 1659 // TODO(danno): We'll soon handle MONOMORPHIC ICs that also support |
1655 // copying COW arrays and silently ignoring some OOB stores into external | 1660 // copying COW arrays and silently ignoring some OOB stores into external |
1656 // arrays, but for now use the generic. | 1661 // arrays, but for now use the generic. |
1657 TRACE_GENERIC_IC(isolate(), "KeyedIC", "COW/OOB external array"); | 1662 TRACE_GENERIC_IC(isolate(), "KeyedIC", "COW/OOB external array"); |
1658 return strict_mode == kStrictMode | 1663 return strict_mode == kStrictMode |
1659 ? generic_stub_strict() | 1664 ? generic_stub_strict() |
1660 : generic_stub(); | 1665 : generic_stub(); |
1661 } | 1666 } |
1662 | 1667 |
1663 State ic_state = target()->ic_state(); | 1668 State ic_state = target()->ic_state(); |
1664 Handle<Map> receiver_map(receiver->map()); | 1669 Handle<Map> receiver_map(receiver->map(), isolate()); |
1665 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | 1670 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
1666 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1671 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
1667 // yet will do so and stay there. | 1672 // yet will do so and stay there. |
1668 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); | 1673 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); |
1669 store_mode = GetNonTransitioningStoreMode(store_mode); | 1674 store_mode = GetNonTransitioningStoreMode(store_mode); |
1670 return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1675 return isolate()->stub_cache()->ComputeKeyedStoreElement( |
1671 monomorphic_map, strict_mode, store_mode); | 1676 monomorphic_map, strict_mode, store_mode); |
1672 } | 1677 } |
1673 | 1678 |
1674 MapHandleList target_receiver_maps; | 1679 MapHandleList target_receiver_maps; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1787 case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: | 1792 case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: |
1788 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: | 1793 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: |
1789 return JSObject::GetElementsTransitionMap(receiver, | 1794 return JSObject::GetElementsTransitionMap(receiver, |
1790 FAST_HOLEY_DOUBLE_ELEMENTS); | 1795 FAST_HOLEY_DOUBLE_ELEMENTS); |
1791 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: | 1796 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: |
1792 ASSERT(receiver->map()->has_external_array_elements()); | 1797 ASSERT(receiver->map()->has_external_array_elements()); |
1793 // Fall through | 1798 // Fall through |
1794 case STORE_NO_TRANSITION_HANDLE_COW: | 1799 case STORE_NO_TRANSITION_HANDLE_COW: |
1795 case STANDARD_STORE: | 1800 case STANDARD_STORE: |
1796 case STORE_AND_GROW_NO_TRANSITION: | 1801 case STORE_AND_GROW_NO_TRANSITION: |
1797 return Handle<Map>(receiver->map()); | 1802 return Handle<Map>(receiver->map(), isolate()); |
1798 } | 1803 } |
1799 return Handle<Map>::null(); | 1804 return Handle<Map>::null(); |
1800 } | 1805 } |
1801 | 1806 |
1802 | 1807 |
1803 bool IsOutOfBoundsAccess(Handle<JSObject> receiver, | 1808 bool IsOutOfBoundsAccess(Handle<JSObject> receiver, |
1804 int index) { | 1809 int index) { |
1805 if (receiver->IsJSArray()) { | 1810 if (receiver->IsJSArray()) { |
1806 return JSArray::cast(*receiver)->length()->IsSmi() && | 1811 return JSArray::cast(*receiver)->length()->IsSmi() && |
1807 index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); | 1812 index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1937 Handle<String> name) { | 1942 Handle<String> name) { |
1938 // If the property has a non-field type allowing map transitions | 1943 // If the property has a non-field type allowing map transitions |
1939 // where there is extra room in the object, we leave the IC in its | 1944 // where there is extra room in the object, we leave the IC in its |
1940 // current state. | 1945 // current state. |
1941 switch (lookup->type()) { | 1946 switch (lookup->type()) { |
1942 case FIELD: | 1947 case FIELD: |
1943 return isolate()->stub_cache()->ComputeKeyedStoreField( | 1948 return isolate()->stub_cache()->ComputeKeyedStoreField( |
1944 name, receiver, lookup->GetFieldIndex().field_index(), | 1949 name, receiver, lookup->GetFieldIndex().field_index(), |
1945 Handle<Map>::null(), strict_mode); | 1950 Handle<Map>::null(), strict_mode); |
1946 case TRANSITION: { | 1951 case TRANSITION: { |
1947 Handle<Map> transition(lookup->GetTransitionTarget()); | 1952 Handle<Map> transition(lookup->GetTransitionTarget(), isolate()); |
1948 int descriptor = transition->LastAdded(); | 1953 int descriptor = transition->LastAdded(); |
1949 | 1954 |
1950 DescriptorArray* target_descriptors = transition->instance_descriptors(); | 1955 DescriptorArray* target_descriptors = transition->instance_descriptors(); |
1951 PropertyDetails details = target_descriptors->GetDetails(descriptor); | 1956 PropertyDetails details = target_descriptors->GetDetails(descriptor); |
1952 | 1957 |
1953 if (details.type() == FIELD && details.attributes() == NONE) { | 1958 if (details.type() == FIELD && details.attributes() == NONE) { |
1954 int field_index = target_descriptors->GetFieldIndex(descriptor); | 1959 int field_index = target_descriptors->GetFieldIndex(descriptor); |
1955 return isolate()->stub_cache()->ComputeKeyedStoreField( | 1960 return isolate()->stub_cache()->ComputeKeyedStoreField( |
1956 name, receiver, field_index, transition, strict_mode); | 1961 name, receiver, field_index, transition, strict_mode); |
1957 } | 1962 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 KeyedCallIC ic(isolate); | 2021 KeyedCallIC ic(isolate); |
2017 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2022 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
2018 MaybeObject* maybe_result = | 2023 MaybeObject* maybe_result = |
2019 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); | 2024 ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1)); |
2020 // Result could be a function or a failure. | 2025 // Result could be a function or a failure. |
2021 JSFunction* raw_function = NULL; | 2026 JSFunction* raw_function = NULL; |
2022 if (!maybe_result->To(&raw_function)) return maybe_result; | 2027 if (!maybe_result->To(&raw_function)) return maybe_result; |
2023 | 2028 |
2024 if (raw_function->is_compiled()) return raw_function; | 2029 if (raw_function->is_compiled()) return raw_function; |
2025 | 2030 |
2026 Handle<JSFunction> function(raw_function); | 2031 Handle<JSFunction> function(raw_function, isolate); |
2027 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); | 2032 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
2028 return *function; | 2033 return *function; |
2029 } | 2034 } |
2030 | 2035 |
2031 | 2036 |
2032 // Used from ic-<arch>.cc. | 2037 // Used from ic-<arch>.cc. |
2033 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { | 2038 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { |
2034 HandleScope scope(isolate); | 2039 HandleScope scope(isolate); |
2035 ASSERT(args.length() == 2); | 2040 ASSERT(args.length() == 2); |
2036 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 2041 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2661 HandleScope scope(isolate()); | 2666 HandleScope scope(isolate()); |
2662 State previous_left, previous_right, previous_state; | 2667 State previous_left, previous_right, previous_state; |
2663 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, | 2668 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, |
2664 &previous_right, &previous_state, NULL); | 2669 &previous_right, &previous_state, NULL); |
2665 State new_left = InputState(previous_left, x); | 2670 State new_left = InputState(previous_left, x); |
2666 State new_right = InputState(previous_right, y); | 2671 State new_right = InputState(previous_right, y); |
2667 State state = TargetState(previous_state, previous_left, previous_right, | 2672 State state = TargetState(previous_state, previous_left, previous_right, |
2668 HasInlinedSmiCode(address()), x, y); | 2673 HasInlinedSmiCode(address()), x, y); |
2669 ICCompareStub stub(op_, new_left, new_right, state); | 2674 ICCompareStub stub(op_, new_left, new_right, state); |
2670 if (state == KNOWN_OBJECT) { | 2675 if (state == KNOWN_OBJECT) { |
2671 stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map())); | 2676 stub.set_known_map( |
| 2677 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); |
2672 } | 2678 } |
2673 set_target(*stub.GetCode(isolate())); | 2679 set_target(*stub.GetCode(isolate())); |
2674 | 2680 |
2675 #ifdef DEBUG | 2681 #ifdef DEBUG |
2676 if (FLAG_trace_ic) { | 2682 if (FLAG_trace_ic) { |
2677 PrintF("[CompareIC in "); | 2683 PrintF("[CompareIC in "); |
2678 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); | 2684 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); |
2679 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", | 2685 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", |
2680 GetStateName(previous_left), | 2686 GetStateName(previous_left), |
2681 GetStateName(previous_right), | 2687 GetStateName(previous_right), |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2737 #undef ADDR | 2743 #undef ADDR |
2738 }; | 2744 }; |
2739 | 2745 |
2740 | 2746 |
2741 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2747 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2742 return IC_utilities[id]; | 2748 return IC_utilities[id]; |
2743 } | 2749 } |
2744 | 2750 |
2745 | 2751 |
2746 } } // namespace v8::internal | 2752 } } // namespace v8::internal |
OLD | NEW |