| 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 if (FLAG_watch_ic_patching) { | 368 if (FLAG_watch_ic_patching) { |
| 369 host->set_profiler_ticks(0); | 369 host->set_profiler_ticks(0); |
| 370 isolate->runtime_profiler()->NotifyICChanged(); | 370 isolate->runtime_profiler()->NotifyICChanged(); |
| 371 } | 371 } |
| 372 // TODO(2029): When an optimized function is patched, it would | 372 // TODO(2029): When an optimized function is patched, it would |
| 373 // be nice to propagate the corresponding type information to its | 373 // be nice to propagate the corresponding type information to its |
| 374 // unoptimized version for the benefit of later inlining. | 374 // unoptimized version for the benefit of later inlining. |
| 375 } | 375 } |
| 376 | 376 |
| 377 | 377 |
| 378 void IC::Clear(Address address) { | 378 void IC::Clear(Isolate* isolate, Address address) { |
| 379 Code* target = GetTargetAtAddress(address); | 379 Code* target = GetTargetAtAddress(address); |
| 380 | 380 |
| 381 // Don't clear debug break inline cache as it will remove the break point. | 381 // Don't clear debug break inline cache as it will remove the break point. |
| 382 if (target->is_debug_stub()) return; | 382 if (target->is_debug_stub()) return; |
| 383 | 383 |
| 384 switch (target->kind()) { | 384 switch (target->kind()) { |
| 385 case Code::LOAD_IC: return LoadIC::Clear(address, target); | 385 case Code::LOAD_IC: return LoadIC::Clear(isolate, address, target); |
| 386 case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target); | 386 case Code::KEYED_LOAD_IC: |
| 387 case Code::STORE_IC: return StoreIC::Clear(address, target); | 387 return KeyedLoadIC::Clear(isolate, address, target); |
| 388 case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target); | 388 case Code::STORE_IC: return StoreIC::Clear(isolate, address, target); |
| 389 case Code::KEYED_STORE_IC: |
| 390 return KeyedStoreIC::Clear(isolate, address, target); |
| 389 case Code::CALL_IC: return CallIC::Clear(address, target); | 391 case Code::CALL_IC: return CallIC::Clear(address, target); |
| 390 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); | 392 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); |
| 391 case Code::COMPARE_IC: return CompareIC::Clear(address, target); | 393 case Code::COMPARE_IC: return CompareIC::Clear(isolate, address, target); |
| 392 case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); | 394 case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); |
| 393 case Code::BINARY_OP_IC: | 395 case Code::BINARY_OP_IC: |
| 394 case Code::TO_BOOLEAN_IC: | 396 case Code::TO_BOOLEAN_IC: |
| 395 // Clearing these is tricky and does not | 397 // Clearing these is tricky and does not |
| 396 // make any performance difference. | 398 // make any performance difference. |
| 397 return; | 399 return; |
| 398 default: UNREACHABLE(); | 400 default: UNREACHABLE(); |
| 399 } | 401 } |
| 400 } | 402 } |
| 401 | 403 |
| 402 | 404 |
| 403 void CallICBase::Clear(Address address, Code* target) { | 405 void CallICBase::Clear(Address address, Code* target) { |
| 404 if (target->ic_state() == UNINITIALIZED) return; | 406 if (target->ic_state() == UNINITIALIZED) return; |
| 405 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); | 407 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); |
| 406 Code* code = | 408 Code* code = |
| 407 Isolate::Current()->stub_cache()->FindCallInitialize( | 409 target->GetIsolate()->stub_cache()->FindCallInitialize( |
| 408 target->arguments_count(), | 410 target->arguments_count(), |
| 409 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, | 411 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, |
| 410 target->kind()); | 412 target->kind()); |
| 411 SetTargetAtAddress(address, code); | 413 SetTargetAtAddress(address, code); |
| 412 } | 414 } |
| 413 | 415 |
| 414 | 416 |
| 415 void KeyedLoadIC::Clear(Address address, Code* target) { | 417 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 416 if (target->ic_state() == UNINITIALIZED) return; | 418 if (target->ic_state() == UNINITIALIZED) return; |
| 417 // Make sure to also clear the map used in inline fast cases. If we | 419 // Make sure to also clear the map used in inline fast cases. If we |
| 418 // do not clear these maps, cached code can keep objects alive | 420 // do not clear these maps, cached code can keep objects alive |
| 419 // through the embedded maps. | 421 // through the embedded maps. |
| 420 SetTargetAtAddress(address, *initialize_stub()); | 422 SetTargetAtAddress(address, *initialize_stub(isolate)); |
| 421 } | 423 } |
| 422 | 424 |
| 423 | 425 |
| 424 void LoadIC::Clear(Address address, Code* target) { | 426 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 425 if (target->ic_state() == UNINITIALIZED) return; | 427 if (target->ic_state() == UNINITIALIZED) return; |
| 426 SetTargetAtAddress(address, *initialize_stub()); | 428 SetTargetAtAddress(address, *initialize_stub(isolate)); |
| 427 } | 429 } |
| 428 | 430 |
| 429 | 431 |
| 430 void StoreIC::Clear(Address address, Code* target) { | 432 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 431 if (target->ic_state() == UNINITIALIZED) return; | 433 if (target->ic_state() == UNINITIALIZED) return; |
| 432 SetTargetAtAddress(address, | 434 SetTargetAtAddress(address, |
| 433 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode) | 435 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode) |
| 434 ? *initialize_stub_strict() | 436 ? *initialize_stub_strict(isolate) |
| 435 : *initialize_stub()); | 437 : *initialize_stub(isolate)); |
| 436 } | 438 } |
| 437 | 439 |
| 438 | 440 |
| 439 void KeyedStoreIC::Clear(Address address, Code* target) { | 441 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 440 if (target->ic_state() == UNINITIALIZED) return; | 442 if (target->ic_state() == UNINITIALIZED) return; |
| 441 SetTargetAtAddress(address, | 443 SetTargetAtAddress(address, |
| 442 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode) | 444 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode) |
| 443 ? *initialize_stub_strict() | 445 ? *initialize_stub_strict(isolate) |
| 444 : *initialize_stub()); | 446 : *initialize_stub(isolate)); |
| 445 } | 447 } |
| 446 | 448 |
| 447 | 449 |
| 448 void CompareIC::Clear(Address address, Code* target) { | 450 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 449 ASSERT(target->major_key() == CodeStub::CompareIC); | 451 ASSERT(target->major_key() == CodeStub::CompareIC); |
| 450 CompareIC::State handler_state; | 452 CompareIC::State handler_state; |
| 451 Token::Value op; | 453 Token::Value op; |
| 452 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, | 454 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, |
| 453 &handler_state, &op); | 455 &handler_state, &op); |
| 454 // Only clear CompareICs that can retain objects. | 456 // Only clear CompareICs that can retain objects. |
| 455 if (handler_state != KNOWN_OBJECT) return; | 457 if (handler_state != KNOWN_OBJECT) return; |
| 456 SetTargetAtAddress(address, GetRawUninitialized(op)); | 458 SetTargetAtAddress(address, GetRawUninitialized(isolate, op)); |
| 457 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); | 459 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); |
| 458 } | 460 } |
| 459 | 461 |
| 460 | 462 |
| 461 static bool HasInterceptorGetter(JSObject* object) { | 463 static bool HasInterceptorGetter(JSObject* object) { |
| 462 return !object->GetNamedInterceptor()->getter()->IsUndefined(); | 464 return !object->GetNamedInterceptor()->getter()->IsUndefined(); |
| 463 } | 465 } |
| 464 | 466 |
| 465 | 467 |
| 466 static void LookupForRead(Handle<Object> object, | 468 static void LookupForRead(Handle<Object> object, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 493 ASSERT(!lookup->IsFound()); | 495 ASSERT(!lookup->IsFound()); |
| 494 return; | 496 return; |
| 495 } | 497 } |
| 496 | 498 |
| 497 object = proto; | 499 object = proto; |
| 498 } | 500 } |
| 499 } | 501 } |
| 500 | 502 |
| 501 | 503 |
| 502 Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { | 504 Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { |
| 503 Handle<Object> delegate = Execution::GetFunctionDelegate(object); | 505 Handle<Object> delegate = Execution::GetFunctionDelegate(isolate(), object); |
| 504 | 506 |
| 505 if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) { | 507 if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) { |
| 506 // Patch the receiver and use the delegate as the function to | 508 // Patch the receiver and use the delegate as the function to |
| 507 // invoke. This is used for invoking objects as if they were functions. | 509 // invoke. This is used for invoking objects as if they were functions. |
| 508 const int argc = target()->arguments_count(); | 510 const int argc = target()->arguments_count(); |
| 509 StackFrameLocator locator(isolate()); | 511 StackFrameLocator locator(isolate()); |
| 510 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 512 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 511 int index = frame->ComputeExpressionsCount() - (argc + 1); | 513 int index = frame->ComputeExpressionsCount() - (argc + 1); |
| 512 frame->SetExpression(index, *object); | 514 frame->SetExpression(index, *object); |
| 513 } | 515 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 // If the object is undefined or null it's illegal to try to get any | 559 // If the object is undefined or null it's illegal to try to get any |
| 558 // of its properties; throw a TypeError in that case. | 560 // of its properties; throw a TypeError in that case. |
| 559 if (object->IsUndefined() || object->IsNull()) { | 561 if (object->IsUndefined() || object->IsNull()) { |
| 560 return TypeError("non_object_property_call", object, name); | 562 return TypeError("non_object_property_call", object, name); |
| 561 } | 563 } |
| 562 | 564 |
| 563 // Check if the name is trivially convertible to an index and get | 565 // Check if the name is trivially convertible to an index and get |
| 564 // the element if so. | 566 // the element if so. |
| 565 uint32_t index; | 567 uint32_t index; |
| 566 if (name->AsArrayIndex(&index)) { | 568 if (name->AsArrayIndex(&index)) { |
| 567 Handle<Object> result = Object::GetElement(object, index); | 569 Handle<Object> result = Object::GetElement(isolate(), object, index); |
| 568 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 570 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 569 if (result->IsJSFunction()) return *result; | 571 if (result->IsJSFunction()) return *result; |
| 570 | 572 |
| 571 // Try to find a suitable function delegate for the object at hand. | 573 // Try to find a suitable function delegate for the object at hand. |
| 572 result = TryCallAsFunction(result); | 574 result = TryCallAsFunction(result); |
| 573 if (result->IsJSFunction()) return *result; | 575 if (result->IsJSFunction()) return *result; |
| 574 | 576 |
| 575 // Otherwise, it will fail in the lookup step. | 577 // Otherwise, it will fail in the lookup step. |
| 576 } | 578 } |
| 577 | 579 |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 if (v8::ToCData<Address>(info->getter()) == 0) break; | 1350 if (v8::ToCData<Address>(info->getter()) == 0) break; |
| 1349 if (!info->IsCompatibleReceiver(*receiver)) break; | 1351 if (!info->IsCompatibleReceiver(*receiver)) break; |
| 1350 return isolate()->stub_cache()->ComputeLoadCallback( | 1352 return isolate()->stub_cache()->ComputeLoadCallback( |
| 1351 name, receiver, holder, info); | 1353 name, receiver, holder, info); |
| 1352 } else if (callback->IsAccessorPair()) { | 1354 } else if (callback->IsAccessorPair()) { |
| 1353 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), | 1355 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), |
| 1354 isolate()); | 1356 isolate()); |
| 1355 if (!getter->IsJSFunction()) break; | 1357 if (!getter->IsJSFunction()) break; |
| 1356 if (holder->IsGlobalObject()) break; | 1358 if (holder->IsGlobalObject()) break; |
| 1357 if (!holder->HasFastProperties()) break; | 1359 if (!holder->HasFastProperties()) break; |
| 1360 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| 1361 CallOptimization call_optimization(function); |
| 1362 if (call_optimization.is_simple_api_call() && |
| 1363 call_optimization.IsCompatibleReceiver(*receiver)) { |
| 1364 return isolate()->stub_cache()->ComputeLoadCallback( |
| 1365 name, receiver, holder, call_optimization); |
| 1366 } |
| 1358 return isolate()->stub_cache()->ComputeLoadViaGetter( | 1367 return isolate()->stub_cache()->ComputeLoadViaGetter( |
| 1359 name, receiver, holder, Handle<JSFunction>::cast(getter)); | 1368 name, receiver, holder, function); |
| 1360 } else if (receiver->IsJSArray() && | 1369 } else if (receiver->IsJSArray() && |
| 1361 name->Equals(isolate()->heap()->length_string())) { | 1370 name->Equals(isolate()->heap()->length_string())) { |
| 1362 PropertyIndex lengthIndex = | 1371 PropertyIndex lengthIndex = |
| 1363 PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize); | 1372 PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize); |
| 1364 return isolate()->stub_cache()->ComputeLoadField( | 1373 return isolate()->stub_cache()->ComputeLoadField( |
| 1365 name, receiver, holder, lengthIndex, Representation::Tagged()); | 1374 name, receiver, holder, lengthIndex, Representation::Tagged()); |
| 1366 } | 1375 } |
| 1367 // TODO(dcarney): Handle correctly. | 1376 // TODO(dcarney): Handle correctly. |
| 1368 if (callback->IsDeclaredAccessorInfo()) break; | 1377 if (callback->IsDeclaredAccessorInfo()) break; |
| 1369 ASSERT(callback->IsForeign()); | 1378 ASSERT(callback->IsForeign()); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 Handle<Object> constant(lookup->GetConstant(), isolate()); | 1544 Handle<Object> constant(lookup->GetConstant(), isolate()); |
| 1536 // TODO(2803): Don't compute a stub for cons strings because they cannot | 1545 // TODO(2803): Don't compute a stub for cons strings because they cannot |
| 1537 // be embedded into code. | 1546 // be embedded into code. |
| 1538 if (constant->IsConsString()) return Handle<Code>::null(); | 1547 if (constant->IsConsString()) return Handle<Code>::null(); |
| 1539 return isolate()->stub_cache()->ComputeKeyedLoadConstant( | 1548 return isolate()->stub_cache()->ComputeKeyedLoadConstant( |
| 1540 name, receiver, holder, constant); | 1549 name, receiver, holder, constant); |
| 1541 } | 1550 } |
| 1542 case CALLBACKS: { | 1551 case CALLBACKS: { |
| 1543 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate()); | 1552 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate()); |
| 1544 // TODO(dcarney): Handle DeclaredAccessorInfo correctly. | 1553 // TODO(dcarney): Handle DeclaredAccessorInfo correctly. |
| 1545 if (!callback_object->IsExecutableAccessorInfo()) break; | 1554 if (callback_object->IsExecutableAccessorInfo()) { |
| 1546 Handle<ExecutableAccessorInfo> callback = | 1555 Handle<ExecutableAccessorInfo> callback = |
| 1547 Handle<ExecutableAccessorInfo>::cast(callback_object); | 1556 Handle<ExecutableAccessorInfo>::cast(callback_object); |
| 1548 if (v8::ToCData<Address>(callback->getter()) == 0) break; | 1557 if (v8::ToCData<Address>(callback->getter()) == 0) break; |
| 1549 if (!callback->IsCompatibleReceiver(*receiver)) break; | 1558 if (!callback->IsCompatibleReceiver(*receiver)) break; |
| 1550 return isolate()->stub_cache()->ComputeKeyedLoadCallback( | 1559 return isolate()->stub_cache()->ComputeKeyedLoadCallback( |
| 1551 name, receiver, holder, callback); | 1560 name, receiver, holder, callback); |
| 1561 } else if (callback_object->IsAccessorPair()) { |
| 1562 Handle<Object> getter( |
| 1563 Handle<AccessorPair>::cast(callback_object)->getter(), |
| 1564 isolate()); |
| 1565 if (!getter->IsJSFunction()) break; |
| 1566 if (holder->IsGlobalObject()) break; |
| 1567 if (!holder->HasFastProperties()) break; |
| 1568 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| 1569 CallOptimization call_optimization(function); |
| 1570 if (call_optimization.is_simple_api_call() && |
| 1571 call_optimization.IsCompatibleReceiver(*receiver)) { |
| 1572 return isolate()->stub_cache()->ComputeKeyedLoadCallback( |
| 1573 name, receiver, holder, call_optimization); |
| 1574 } |
| 1575 } |
| 1576 break; |
| 1552 } | 1577 } |
| 1553 case INTERCEPTOR: | 1578 case INTERCEPTOR: |
| 1554 ASSERT(HasInterceptorGetter(lookup->holder())); | 1579 ASSERT(HasInterceptorGetter(lookup->holder())); |
| 1555 return isolate()->stub_cache()->ComputeKeyedLoadInterceptor( | 1580 return isolate()->stub_cache()->ComputeKeyedLoadInterceptor( |
| 1556 name, receiver, holder); | 1581 name, receiver, holder); |
| 1557 default: | 1582 default: |
| 1558 // Always rewrite to the generic case so that we do not | 1583 // Always rewrite to the generic case so that we do not |
| 1559 // repeatedly try to rewrite. | 1584 // repeatedly try to rewrite. |
| 1560 return generic_stub(); | 1585 return generic_stub(); |
| 1561 } | 1586 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 ? global_proxy_stub_strict() | 1727 ? global_proxy_stub_strict() |
| 1703 : global_proxy_stub(); | 1728 : global_proxy_stub(); |
| 1704 set_target(*stub); | 1729 set_target(*stub); |
| 1705 TRACE_IC("StoreIC", name, state, *stub); | 1730 TRACE_IC("StoreIC", name, state, *stub); |
| 1706 } | 1731 } |
| 1707 return JSReceiver::SetPropertyOrFail( | 1732 return JSReceiver::SetPropertyOrFail( |
| 1708 receiver, name, value, NONE, strict_mode, store_mode); | 1733 receiver, name, value, NONE, strict_mode, store_mode); |
| 1709 } | 1734 } |
| 1710 | 1735 |
| 1711 LookupResult lookup(isolate()); | 1736 LookupResult lookup(isolate()); |
| 1712 if (LookupForWrite(receiver, name, value, &lookup, &state)) { | 1737 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); |
| 1713 if (FLAG_use_ic) { | 1738 if (!can_store && |
| 1714 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); | 1739 strict_mode == kStrictMode && |
| 1715 } | 1740 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
| 1716 } else if (strict_mode == kStrictMode && | 1741 IsUndeclaredGlobal(object)) { |
| 1717 !(lookup.IsProperty() && lookup.IsReadOnly()) && | |
| 1718 IsUndeclaredGlobal(object)) { | |
| 1719 // Strict mode doesn't allow setting non-existent global property. | 1742 // Strict mode doesn't allow setting non-existent global property. |
| 1720 return ReferenceError("not_defined", name); | 1743 return ReferenceError("not_defined", name); |
| 1721 } else if (FLAG_use_ic && | 1744 } |
| 1722 (!name->IsCacheable(isolate()) || | 1745 if (FLAG_use_ic) { |
| 1723 lookup.IsNormal() || | 1746 if (state == UNINITIALIZED) { |
| 1724 (lookup.IsField() && lookup.CanHoldValue(value)))) { | 1747 Handle<Code> stub = (strict_mode == kStrictMode) |
| 1725 Handle<Code> stub = strict_mode == kStrictMode | 1748 ? pre_monomorphic_stub_strict() |
| 1726 ? generic_stub_strict() : generic_stub(); | 1749 : pre_monomorphic_stub(); |
| 1727 set_target(*stub); | 1750 set_target(*stub); |
| 1751 TRACE_IC("StoreIC", name, state, *stub); |
| 1752 } else if (can_store) { |
| 1753 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); |
| 1754 } else if (!name->IsCacheable(isolate()) || |
| 1755 lookup.IsNormal() || |
| 1756 (lookup.IsField() && lookup.CanHoldValue(value))) { |
| 1757 Handle<Code> stub = (strict_mode == kStrictMode) ? generic_stub_strict() |
| 1758 : generic_stub(); |
| 1759 set_target(*stub); |
| 1760 } |
| 1728 } | 1761 } |
| 1729 | 1762 |
| 1730 // Set the property. | 1763 // Set the property. |
| 1731 return JSReceiver::SetPropertyOrFail( | 1764 return JSReceiver::SetPropertyOrFail( |
| 1732 receiver, name, value, NONE, strict_mode, store_mode); | 1765 receiver, name, value, NONE, strict_mode, store_mode); |
| 1733 } | 1766 } |
| 1734 | 1767 |
| 1735 | 1768 |
| 1736 void StoreIC::UpdateCaches(LookupResult* lookup, | 1769 void StoreIC::UpdateCaches(LookupResult* lookup, |
| 1737 State state, | 1770 State state, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1791 if (!holder->HasFastProperties()) break; | 1824 if (!holder->HasFastProperties()) break; |
| 1792 if (!info->IsCompatibleReceiver(*receiver)) break; | 1825 if (!info->IsCompatibleReceiver(*receiver)) break; |
| 1793 return isolate()->stub_cache()->ComputeStoreCallback( | 1826 return isolate()->stub_cache()->ComputeStoreCallback( |
| 1794 name, receiver, holder, info, strict_mode); | 1827 name, receiver, holder, info, strict_mode); |
| 1795 } else if (callback->IsAccessorPair()) { | 1828 } else if (callback->IsAccessorPair()) { |
| 1796 Handle<Object> setter( | 1829 Handle<Object> setter( |
| 1797 Handle<AccessorPair>::cast(callback)->setter(), isolate()); | 1830 Handle<AccessorPair>::cast(callback)->setter(), isolate()); |
| 1798 if (!setter->IsJSFunction()) break; | 1831 if (!setter->IsJSFunction()) break; |
| 1799 if (holder->IsGlobalObject()) break; | 1832 if (holder->IsGlobalObject()) break; |
| 1800 if (!holder->HasFastProperties()) break; | 1833 if (!holder->HasFastProperties()) break; |
| 1834 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); |
| 1835 CallOptimization call_optimization(function); |
| 1836 if (call_optimization.is_simple_api_call() && |
| 1837 call_optimization.IsCompatibleReceiver(*receiver)) { |
| 1838 return isolate()->stub_cache()->ComputeStoreCallback( |
| 1839 name, receiver, holder, call_optimization, strict_mode); |
| 1840 } |
| 1801 return isolate()->stub_cache()->ComputeStoreViaSetter( | 1841 return isolate()->stub_cache()->ComputeStoreViaSetter( |
| 1802 name, receiver, holder, Handle<JSFunction>::cast(setter), | 1842 name, receiver, holder, Handle<JSFunction>::cast(setter), |
| 1803 strict_mode); | 1843 strict_mode); |
| 1804 } | 1844 } |
| 1805 // TODO(dcarney): Handle correctly. | 1845 // TODO(dcarney): Handle correctly. |
| 1806 if (callback->IsDeclaredAccessorInfo()) break; | 1846 if (callback->IsDeclaredAccessorInfo()) break; |
| 1807 ASSERT(callback->IsForeign()); | 1847 ASSERT(callback->IsForeign()); |
| 1808 // No IC support for old-style native accessors. | 1848 // No IC support for old-style native accessors. |
| 1809 break; | 1849 break; |
| 1810 } | 1850 } |
| (...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2752 builtin = builtins->javascript_builtin(Builtins::SHL); | 2792 builtin = builtins->javascript_builtin(Builtins::SHL); |
| 2753 break; | 2793 break; |
| 2754 default: | 2794 default: |
| 2755 UNREACHABLE(); | 2795 UNREACHABLE(); |
| 2756 } | 2796 } |
| 2757 | 2797 |
| 2758 Handle<JSFunction> builtin_function(JSFunction::cast(builtin), isolate); | 2798 Handle<JSFunction> builtin_function(JSFunction::cast(builtin), isolate); |
| 2759 | 2799 |
| 2760 bool caught_exception; | 2800 bool caught_exception; |
| 2761 Handle<Object> builtin_args[] = { right }; | 2801 Handle<Object> builtin_args[] = { right }; |
| 2762 Handle<Object> result = Execution::Call(builtin_function, | 2802 Handle<Object> result = Execution::Call(isolate, |
| 2803 builtin_function, |
| 2763 left, | 2804 left, |
| 2764 ARRAY_SIZE(builtin_args), | 2805 ARRAY_SIZE(builtin_args), |
| 2765 builtin_args, | 2806 builtin_args, |
| 2766 &caught_exception); | 2807 &caught_exception); |
| 2767 if (caught_exception) { | 2808 if (caught_exception) { |
| 2768 return Failure::Exception(); | 2809 return Failure::Exception(); |
| 2769 } | 2810 } |
| 2770 return *result; | 2811 return *result; |
| 2771 } | 2812 } |
| 2772 | 2813 |
| 2773 | 2814 |
| 2774 Code* CompareIC::GetRawUninitialized(Token::Value op) { | 2815 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { |
| 2775 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); | 2816 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); |
| 2776 Code* code = NULL; | 2817 Code* code = NULL; |
| 2777 CHECK(stub.FindCodeInCache(&code, Isolate::Current())); | 2818 CHECK(stub.FindCodeInCache(&code, isolate)); |
| 2778 return code; | 2819 return code; |
| 2779 } | 2820 } |
| 2780 | 2821 |
| 2781 | 2822 |
| 2782 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { | 2823 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { |
| 2783 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); | 2824 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); |
| 2784 return stub.GetCode(isolate); | 2825 return stub.GetCode(isolate); |
| 2785 } | 2826 } |
| 2786 | 2827 |
| 2787 | 2828 |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3095 #undef ADDR | 3136 #undef ADDR |
| 3096 }; | 3137 }; |
| 3097 | 3138 |
| 3098 | 3139 |
| 3099 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3140 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3100 return IC_utilities[id]; | 3141 return IC_utilities[id]; |
| 3101 } | 3142 } |
| 3102 | 3143 |
| 3103 | 3144 |
| 3104 } } // namespace v8::internal | 3145 } } // namespace v8::internal |
| OLD | NEW |