| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/field-index.h" | 9 #include "src/field-index.h" |
| 10 #include "src/hydrogen.h" | 10 #include "src/hydrogen.h" |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 template <> | 316 template <> |
| 317 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { | 317 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { |
| 318 Factory* factory = isolate()->factory(); | 318 Factory* factory = isolate()->factory(); |
| 319 HValue* undefined = graph()->GetConstantUndefined(); | 319 HValue* undefined = graph()->GetConstantUndefined(); |
| 320 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); | 320 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); |
| 321 | 321 |
| 322 // This stub is very performance sensitive, the generated code must be tuned | 322 // This stub is very performance sensitive, the generated code must be tuned |
| 323 // so that it doesn't build and eager frame. | 323 // so that it doesn't build and eager frame. |
| 324 info()->MarkMustNotHaveEagerFrame(); | 324 info()->MarkMustNotHaveEagerFrame(); |
| 325 | 325 |
| 326 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0), | 326 HInstruction* allocation_site = |
| 327 GetParameter(1), | 327 Add<HLoadKeyed>(GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS); |
| 328 static_cast<HValue*>(NULL), | |
| 329 FAST_ELEMENTS); | |
| 330 IfBuilder checker(this); | 328 IfBuilder checker(this); |
| 331 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, | 329 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
| 332 undefined); | 330 undefined); |
| 333 checker.Then(); | 331 checker.Then(); |
| 334 | 332 |
| 335 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 333 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 336 AllocationSite::kTransitionInfoOffset); | 334 AllocationSite::kTransitionInfoOffset); |
| 337 HInstruction* boilerplate = Add<HLoadNamedField>( | 335 HInstruction* boilerplate = |
| 338 allocation_site, static_cast<HValue*>(NULL), access); | 336 Add<HLoadNamedField>(allocation_site, nullptr, access); |
| 339 HValue* elements = AddLoadElements(boilerplate); | 337 HValue* elements = AddLoadElements(boilerplate); |
| 340 HValue* capacity = AddLoadFixedArrayLength(elements); | 338 HValue* capacity = AddLoadFixedArrayLength(elements); |
| 341 IfBuilder zero_capacity(this); | 339 IfBuilder zero_capacity(this); |
| 342 zero_capacity.If<HCompareNumericAndBranch>(capacity, graph()->GetConstant0(), | 340 zero_capacity.If<HCompareNumericAndBranch>(capacity, graph()->GetConstant0(), |
| 343 Token::EQ); | 341 Token::EQ); |
| 344 zero_capacity.Then(); | 342 zero_capacity.Then(); |
| 345 Push(BuildCloneShallowArrayEmpty(boilerplate, | 343 Push(BuildCloneShallowArrayEmpty(boilerplate, |
| 346 allocation_site, | 344 allocation_site, |
| 347 alloc_site_mode)); | 345 alloc_site_mode)); |
| 348 zero_capacity.Else(); | 346 zero_capacity.Else(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 | 378 |
| 381 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { | 379 Handle<Code> FastCloneShallowArrayStub::GenerateCode() { |
| 382 return DoGenerateCode(this); | 380 return DoGenerateCode(this); |
| 383 } | 381 } |
| 384 | 382 |
| 385 | 383 |
| 386 template <> | 384 template <> |
| 387 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { | 385 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { |
| 388 HValue* undefined = graph()->GetConstantUndefined(); | 386 HValue* undefined = graph()->GetConstantUndefined(); |
| 389 | 387 |
| 390 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0), | 388 HInstruction* allocation_site = |
| 391 GetParameter(1), | 389 Add<HLoadKeyed>(GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS); |
| 392 static_cast<HValue*>(NULL), | |
| 393 FAST_ELEMENTS); | |
| 394 | 390 |
| 395 IfBuilder checker(this); | 391 IfBuilder checker(this); |
| 396 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, | 392 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, |
| 397 undefined); | 393 undefined); |
| 398 checker.And(); | 394 checker.And(); |
| 399 | 395 |
| 400 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( | 396 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
| 401 AllocationSite::kTransitionInfoOffset); | 397 AllocationSite::kTransitionInfoOffset); |
| 402 HInstruction* boilerplate = Add<HLoadNamedField>( | 398 HInstruction* boilerplate = |
| 403 allocation_site, static_cast<HValue*>(NULL), access); | 399 Add<HLoadNamedField>(allocation_site, nullptr, access); |
| 404 | 400 |
| 405 int length = casted_stub()->length(); | 401 int length = casted_stub()->length(); |
| 406 if (length == 0) { | 402 if (length == 0) { |
| 407 // Empty objects have some slack added to them. | 403 // Empty objects have some slack added to them. |
| 408 length = JSObject::kInitialGlobalObjectUnusedPropertiesCount; | 404 length = JSObject::kInitialGlobalObjectUnusedPropertiesCount; |
| 409 } | 405 } |
| 410 int size = JSObject::kHeaderSize + length * kPointerSize; | 406 int size = JSObject::kHeaderSize + length * kPointerSize; |
| 411 int object_size = size; | 407 int object_size = size; |
| 412 if (FLAG_allocation_site_pretenuring) { | 408 if (FLAG_allocation_site_pretenuring) { |
| 413 size += AllocationMemento::kSize; | 409 size += AllocationMemento::kSize; |
| 414 } | 410 } |
| 415 | 411 |
| 416 HValue* boilerplate_map = Add<HLoadNamedField>( | 412 HValue* boilerplate_map = |
| 417 boilerplate, static_cast<HValue*>(NULL), | 413 Add<HLoadNamedField>(boilerplate, nullptr, HObjectAccess::ForMap()); |
| 418 HObjectAccess::ForMap()); | |
| 419 HValue* boilerplate_size = Add<HLoadNamedField>( | 414 HValue* boilerplate_size = Add<HLoadNamedField>( |
| 420 boilerplate_map, static_cast<HValue*>(NULL), | 415 boilerplate_map, nullptr, HObjectAccess::ForMapInstanceSize()); |
| 421 HObjectAccess::ForMapInstanceSize()); | |
| 422 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); | 416 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); |
| 423 checker.If<HCompareNumericAndBranch>(boilerplate_size, | 417 checker.If<HCompareNumericAndBranch>(boilerplate_size, |
| 424 size_in_words, Token::EQ); | 418 size_in_words, Token::EQ); |
| 425 checker.Then(); | 419 checker.Then(); |
| 426 | 420 |
| 427 HValue* size_in_bytes = Add<HConstant>(size); | 421 HValue* size_in_bytes = Add<HConstant>(size); |
| 428 | 422 |
| 429 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), | 423 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), |
| 430 NOT_TENURED, JS_OBJECT_TYPE); | 424 NOT_TENURED, JS_OBJECT_TYPE); |
| 431 | 425 |
| 432 for (int i = 0; i < object_size; i += kPointerSize) { | 426 for (int i = 0; i < object_size; i += kPointerSize) { |
| 433 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i); | 427 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i); |
| 434 Add<HStoreNamedField>( | 428 Add<HStoreNamedField>(object, access, |
| 435 object, access, Add<HLoadNamedField>( | 429 Add<HLoadNamedField>(boilerplate, nullptr, access)); |
| 436 boilerplate, static_cast<HValue*>(NULL), access)); | |
| 437 } | 430 } |
| 438 | 431 |
| 439 DCHECK(FLAG_allocation_site_pretenuring || (size == object_size)); | 432 DCHECK(FLAG_allocation_site_pretenuring || (size == object_size)); |
| 440 if (FLAG_allocation_site_pretenuring) { | 433 if (FLAG_allocation_site_pretenuring) { |
| 441 BuildCreateAllocationMemento( | 434 BuildCreateAllocationMemento( |
| 442 object, Add<HConstant>(object_size), allocation_site); | 435 object, Add<HConstant>(object_size), allocation_site); |
| 443 } | 436 } |
| 444 | 437 |
| 445 environment()->Push(object); | 438 environment()->Push(object); |
| 446 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); | 439 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 488 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
| 496 Add<HStoreNamedField>( | 489 Add<HStoreNamedField>( |
| 497 object, | 490 object, |
| 498 HObjectAccess::ForAllocationSiteOffset( | 491 HObjectAccess::ForAllocationSiteOffset( |
| 499 AllocationSite::kDependentCodeOffset), | 492 AllocationSite::kDependentCodeOffset), |
| 500 empty_fixed_array); | 493 empty_fixed_array); |
| 501 | 494 |
| 502 // Link the object to the allocation site list | 495 // Link the object to the allocation site list |
| 503 HValue* site_list = Add<HConstant>( | 496 HValue* site_list = Add<HConstant>( |
| 504 ExternalReference::allocation_sites_list_address(isolate())); | 497 ExternalReference::allocation_sites_list_address(isolate())); |
| 505 HValue* site = Add<HLoadNamedField>( | 498 HValue* site = Add<HLoadNamedField>(site_list, nullptr, |
| 506 site_list, static_cast<HValue*>(NULL), | 499 HObjectAccess::ForAllocationSiteList()); |
| 507 HObjectAccess::ForAllocationSiteList()); | |
| 508 // TODO(mvstanton): This is a store to a weak pointer, which we may want to | 500 // TODO(mvstanton): This is a store to a weak pointer, which we may want to |
| 509 // mark as such in order to skip the write barrier, once we have a unified | 501 // mark as such in order to skip the write barrier, once we have a unified |
| 510 // system for weakness. For now we decided to keep it like this because having | 502 // system for weakness. For now we decided to keep it like this because having |
| 511 // an initial write barrier backed store makes this pointer strong until the | 503 // an initial write barrier backed store makes this pointer strong until the |
| 512 // next GC, and allocation sites are designed to survive several GCs anyway. | 504 // next GC, and allocation sites are designed to survive several GCs anyway. |
| 513 Add<HStoreNamedField>( | 505 Add<HStoreNamedField>( |
| 514 object, | 506 object, |
| 515 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), | 507 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset), |
| 516 site); | 508 site); |
| 517 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), | 509 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 529 return DoGenerateCode(this); | 521 return DoGenerateCode(this); |
| 530 } | 522 } |
| 531 | 523 |
| 532 | 524 |
| 533 template <> | 525 template <> |
| 534 HValue* CodeStubGraphBuilder<LoadScriptContextFieldStub>::BuildCodeStub() { | 526 HValue* CodeStubGraphBuilder<LoadScriptContextFieldStub>::BuildCodeStub() { |
| 535 int context_index = casted_stub()->context_index(); | 527 int context_index = casted_stub()->context_index(); |
| 536 int slot_index = casted_stub()->slot_index(); | 528 int slot_index = casted_stub()->slot_index(); |
| 537 | 529 |
| 538 HValue* script_context = BuildGetScriptContext(context_index); | 530 HValue* script_context = BuildGetScriptContext(context_index); |
| 539 return Add<HLoadNamedField>(script_context, static_cast<HValue*>(NULL), | 531 return Add<HLoadNamedField>(script_context, nullptr, |
| 540 HObjectAccess::ForContextSlot(slot_index)); | 532 HObjectAccess::ForContextSlot(slot_index)); |
| 541 } | 533 } |
| 542 | 534 |
| 543 | 535 |
| 544 Handle<Code> LoadScriptContextFieldStub::GenerateCode() { | 536 Handle<Code> LoadScriptContextFieldStub::GenerateCode() { |
| 545 return DoGenerateCode(this); | 537 return DoGenerateCode(this); |
| 546 } | 538 } |
| 547 | 539 |
| 548 | 540 |
| 549 template <> | 541 template <> |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 ? Representation::Double() | 578 ? Representation::Double() |
| 587 : Representation::Tagged(); | 579 : Representation::Tagged(); |
| 588 int offset = index.offset(); | 580 int offset = index.offset(); |
| 589 HObjectAccess access = index.is_inobject() | 581 HObjectAccess access = index.is_inobject() |
| 590 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) | 582 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) |
| 591 : HObjectAccess::ForBackingStoreOffset(offset, representation); | 583 : HObjectAccess::ForBackingStoreOffset(offset, representation); |
| 592 if (index.is_double() && | 584 if (index.is_double() && |
| 593 (!FLAG_unbox_double_fields || !index.is_inobject())) { | 585 (!FLAG_unbox_double_fields || !index.is_inobject())) { |
| 594 // Load the heap number. | 586 // Load the heap number. |
| 595 object = Add<HLoadNamedField>( | 587 object = Add<HLoadNamedField>( |
| 596 object, static_cast<HValue*>(NULL), | 588 object, nullptr, access.WithRepresentation(Representation::Tagged())); |
| 597 access.WithRepresentation(Representation::Tagged())); | |
| 598 // Load the double value from it. | 589 // Load the double value from it. |
| 599 access = HObjectAccess::ForHeapNumberValue(); | 590 access = HObjectAccess::ForHeapNumberValue(); |
| 600 } | 591 } |
| 601 return Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), access); | 592 return Add<HLoadNamedField>(object, nullptr, access); |
| 602 } | 593 } |
| 603 | 594 |
| 604 | 595 |
| 605 template<> | 596 template<> |
| 606 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { | 597 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { |
| 607 return BuildLoadNamedField(GetParameter(0), casted_stub()->index()); | 598 return BuildLoadNamedField(GetParameter(0), casted_stub()->index()); |
| 608 } | 599 } |
| 609 | 600 |
| 610 | 601 |
| 611 Handle<Code> LoadFieldStub::GenerateCode() { | 602 Handle<Code> LoadFieldStub::GenerateCode() { |
| 612 return DoGenerateCode(this); | 603 return DoGenerateCode(this); |
| 613 } | 604 } |
| 614 | 605 |
| 615 | 606 |
| 616 template <> | 607 template <> |
| 617 HValue* CodeStubGraphBuilder<LoadConstantStub>::BuildCodeStub() { | 608 HValue* CodeStubGraphBuilder<LoadConstantStub>::BuildCodeStub() { |
| 618 HValue* map = AddLoadMap(GetParameter(0), NULL); | 609 HValue* map = AddLoadMap(GetParameter(0), NULL); |
| 619 HObjectAccess descriptors_access = HObjectAccess::ForObservableJSObjectOffset( | 610 HObjectAccess descriptors_access = HObjectAccess::ForObservableJSObjectOffset( |
| 620 Map::kDescriptorsOffset, Representation::Tagged()); | 611 Map::kDescriptorsOffset, Representation::Tagged()); |
| 621 HValue* descriptors = | 612 HValue* descriptors = Add<HLoadNamedField>(map, nullptr, descriptors_access); |
| 622 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), descriptors_access); | |
| 623 HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset( | 613 HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset( |
| 624 DescriptorArray::GetValueOffset(casted_stub()->constant_index())); | 614 DescriptorArray::GetValueOffset(casted_stub()->constant_index())); |
| 625 return Add<HLoadNamedField>(descriptors, static_cast<HValue*>(NULL), | 615 return Add<HLoadNamedField>(descriptors, nullptr, value_access); |
| 626 value_access); | |
| 627 } | 616 } |
| 628 | 617 |
| 629 | 618 |
| 630 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } | 619 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } |
| 631 | 620 |
| 632 | 621 |
| 633 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { | 622 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { |
| 634 HValue* result; | 623 HValue* result; |
| 635 HInstruction* backing_store = Add<HLoadKeyed>( | 624 HInstruction* backing_store = |
| 636 elements, graph()->GetConstant1(), static_cast<HValue*>(NULL), | 625 Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS, |
| 637 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 626 ALLOW_RETURN_HOLE); |
| 638 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map()); | 627 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map()); |
| 639 HValue* backing_store_length = | 628 HValue* backing_store_length = Add<HLoadNamedField>( |
| 640 Add<HLoadNamedField>(backing_store, static_cast<HValue*>(NULL), | 629 backing_store, nullptr, HObjectAccess::ForFixedArrayLength()); |
| 641 HObjectAccess::ForFixedArrayLength()); | |
| 642 IfBuilder in_unmapped_range(this); | 630 IfBuilder in_unmapped_range(this); |
| 643 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, | 631 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, |
| 644 Token::LT); | 632 Token::LT); |
| 645 in_unmapped_range.Then(); | 633 in_unmapped_range.Then(); |
| 646 { | 634 { |
| 647 result = Add<HLoadKeyed>(backing_store, key, static_cast<HValue*>(NULL), | 635 result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, |
| 648 FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE); | 636 NEVER_RETURN_HOLE); |
| 649 } | 637 } |
| 650 in_unmapped_range.ElseDeopt("Outside of range"); | 638 in_unmapped_range.ElseDeopt("Outside of range"); |
| 651 in_unmapped_range.End(); | 639 in_unmapped_range.End(); |
| 652 return result; | 640 return result; |
| 653 } | 641 } |
| 654 | 642 |
| 655 | 643 |
| 656 template <> | 644 template <> |
| 657 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { | 645 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { |
| 658 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); | 646 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 685 // context[t]. | 673 // context[t]. |
| 686 | 674 |
| 687 key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); | 675 key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); |
| 688 IfBuilder positive_smi(this); | 676 IfBuilder positive_smi(this); |
| 689 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), | 677 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), |
| 690 Token::LT); | 678 Token::LT); |
| 691 positive_smi.ThenDeopt("key is negative"); | 679 positive_smi.ThenDeopt("key is negative"); |
| 692 positive_smi.End(); | 680 positive_smi.End(); |
| 693 | 681 |
| 694 HValue* constant_two = Add<HConstant>(2); | 682 HValue* constant_two = Add<HConstant>(2); |
| 695 HValue* elements = AddLoadElements(receiver, static_cast<HValue*>(NULL)); | 683 HValue* elements = AddLoadElements(receiver, nullptr); |
| 696 HValue* elements_length = | 684 HValue* elements_length = Add<HLoadNamedField>( |
| 697 Add<HLoadNamedField>(elements, static_cast<HValue*>(NULL), | 685 elements, nullptr, HObjectAccess::ForFixedArrayLength()); |
| 698 HObjectAccess::ForFixedArrayLength()); | |
| 699 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); | 686 HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two); |
| 700 IfBuilder in_range(this); | 687 IfBuilder in_range(this); |
| 701 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); | 688 in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT); |
| 702 in_range.Then(); | 689 in_range.Then(); |
| 703 { | 690 { |
| 704 HValue* index = AddUncasted<HAdd>(key, constant_two); | 691 HValue* index = AddUncasted<HAdd>(key, constant_two); |
| 705 HInstruction* mapped_index = | 692 HInstruction* mapped_index = Add<HLoadKeyed>( |
| 706 Add<HLoadKeyed>(elements, index, static_cast<HValue*>(NULL), | 693 elements, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); |
| 707 FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE); | |
| 708 | 694 |
| 709 IfBuilder is_valid(this); | 695 IfBuilder is_valid(this); |
| 710 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index, | 696 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index, |
| 711 graph()->GetConstantHole()); | 697 graph()->GetConstantHole()); |
| 712 is_valid.Then(); | 698 is_valid.Then(); |
| 713 { | 699 { |
| 714 // TODO(mvstanton): I'd like to assert from this point, that if the | 700 // TODO(mvstanton): I'd like to assert from this point, that if the |
| 715 // mapped_index is not the hole that it is indeed, a smi. An unnecessary | 701 // mapped_index is not the hole that it is indeed, a smi. An unnecessary |
| 716 // smi check is being emitted. | 702 // smi check is being emitted. |
| 717 HValue* the_context = | 703 HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(), |
| 718 Add<HLoadKeyed>(elements, graph()->GetConstant0(), | 704 nullptr, FAST_ELEMENTS); |
| 719 static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
| 720 DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize); | 705 DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize); |
| 721 HValue* result = | 706 HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr, |
| 722 Add<HLoadKeyed>(the_context, mapped_index, static_cast<HValue*>(NULL), | 707 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 723 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
| 724 environment()->Push(result); | 708 environment()->Push(result); |
| 725 } | 709 } |
| 726 is_valid.Else(); | 710 is_valid.Else(); |
| 727 { | 711 { |
| 728 HValue* result = UnmappedCase(elements, key); | 712 HValue* result = UnmappedCase(elements, key); |
| 729 environment()->Push(result); | 713 environment()->Push(result); |
| 730 } | 714 } |
| 731 is_valid.End(); | 715 is_valid.End(); |
| 732 } | 716 } |
| 733 in_range.Else(); | 717 in_range.Else(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 MUTABLE_HEAP_NUMBER_TYPE); | 755 MUTABLE_HEAP_NUMBER_TYPE); |
| 772 AddStoreMapConstant(heap_number, | 756 AddStoreMapConstant(heap_number, |
| 773 isolate()->factory()->mutable_heap_number_map()); | 757 isolate()->factory()->mutable_heap_number_map()); |
| 774 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), | 758 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
| 775 value); | 759 value); |
| 776 // Store the new mutable heap number into the object. | 760 // Store the new mutable heap number into the object. |
| 777 access = heap_number_access; | 761 access = heap_number_access; |
| 778 value = heap_number; | 762 value = heap_number; |
| 779 } else { | 763 } else { |
| 780 // Load the heap number. | 764 // Load the heap number. |
| 781 object = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 765 object = Add<HLoadNamedField>(object, nullptr, heap_number_access); |
| 782 heap_number_access); | |
| 783 // Store the double value into it. | 766 // Store the double value into it. |
| 784 access = HObjectAccess::ForHeapNumberValue(); | 767 access = HObjectAccess::ForHeapNumberValue(); |
| 785 } | 768 } |
| 786 } | 769 } |
| 787 } else if (representation.IsHeapObject()) { | 770 } else if (representation.IsHeapObject()) { |
| 788 BuildCheckHeapObject(value); | 771 BuildCheckHeapObject(value); |
| 789 } | 772 } |
| 790 | 773 |
| 791 Add<HStoreNamedField>(object, access, value, INITIALIZING_STORE); | 774 Add<HStoreNamedField>(object, access, value, INITIALIZING_STORE); |
| 792 } | 775 } |
| 793 | 776 |
| 794 | 777 |
| 795 template <> | 778 template <> |
| 796 HValue* CodeStubGraphBuilder<StoreFieldStub>::BuildCodeStub() { | 779 HValue* CodeStubGraphBuilder<StoreFieldStub>::BuildCodeStub() { |
| 797 BuildStoreNamedField(GetParameter(0), GetParameter(2), casted_stub()->index(), | 780 BuildStoreNamedField(GetParameter(0), GetParameter(2), casted_stub()->index(), |
| 798 casted_stub()->representation(), false); | 781 casted_stub()->representation(), false); |
| 799 return GetParameter(2); | 782 return GetParameter(2); |
| 800 } | 783 } |
| 801 | 784 |
| 802 | 785 |
| 803 Handle<Code> StoreFieldStub::GenerateCode() { return DoGenerateCode(this); } | 786 Handle<Code> StoreFieldStub::GenerateCode() { return DoGenerateCode(this); } |
| 804 | 787 |
| 805 | 788 |
| 806 template <> | 789 template <> |
| 807 HValue* CodeStubGraphBuilder<StoreTransitionStub>::BuildCodeStub() { | 790 HValue* CodeStubGraphBuilder<StoreTransitionStub>::BuildCodeStub() { |
| 808 HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex); | 791 HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex); |
| 809 | 792 |
| 810 switch (casted_stub()->store_mode()) { | 793 switch (casted_stub()->store_mode()) { |
| 811 case StoreTransitionStub::ExtendStorageAndStoreMapAndValue: { | 794 case StoreTransitionStub::ExtendStorageAndStoreMapAndValue: { |
| 812 HValue* properties = | 795 HValue* properties = Add<HLoadNamedField>( |
| 813 Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 796 object, nullptr, HObjectAccess::ForPropertiesPointer()); |
| 814 HObjectAccess::ForPropertiesPointer()); | |
| 815 HValue* length = AddLoadFixedArrayLength(properties); | 797 HValue* length = AddLoadFixedArrayLength(properties); |
| 816 HValue* delta = | 798 HValue* delta = |
| 817 Add<HConstant>(static_cast<int32_t>(JSObject::kFieldsAdded)); | 799 Add<HConstant>(static_cast<int32_t>(JSObject::kFieldsAdded)); |
| 818 HValue* new_capacity = AddUncasted<HAdd>(length, delta); | 800 HValue* new_capacity = AddUncasted<HAdd>(length, delta); |
| 819 | 801 |
| 820 // Grow properties array. | 802 // Grow properties array. |
| 821 ElementsKind kind = FAST_ELEMENTS; | 803 ElementsKind kind = FAST_ELEMENTS; |
| 822 Add<HBoundsCheck>(new_capacity, | 804 Add<HBoundsCheck>(new_capacity, |
| 823 Add<HConstant>((Page::kMaxRegularHeapObjectSize - | 805 Add<HConstant>((Page::kMaxRegularHeapObjectSize - |
| 824 FixedArray::kHeaderSize) >> | 806 FixedArray::kHeaderSize) >> |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 // Check that the map of the global has not changed: use a placeholder map | 1320 // Check that the map of the global has not changed: use a placeholder map |
| 1339 // that will be replaced later with the global object's map. | 1321 // that will be replaced later with the global object's map. |
| 1340 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); | 1322 Handle<Map> placeholder_map = isolate()->factory()->meta_map(); |
| 1341 HValue* global = Add<HConstant>( | 1323 HValue* global = Add<HConstant>( |
| 1342 StoreGlobalStub::global_placeholder(isolate())); | 1324 StoreGlobalStub::global_placeholder(isolate())); |
| 1343 Add<HCheckMaps>(global, placeholder_map); | 1325 Add<HCheckMaps>(global, placeholder_map); |
| 1344 } | 1326 } |
| 1345 | 1327 |
| 1346 HValue* cell = Add<HConstant>(placeholder_cell); | 1328 HValue* cell = Add<HConstant>(placeholder_cell); |
| 1347 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); | 1329 HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); |
| 1348 HValue* cell_contents = Add<HLoadNamedField>( | 1330 HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access); |
| 1349 cell, static_cast<HValue*>(NULL), access); | |
| 1350 | 1331 |
| 1351 if (stub->is_constant()) { | 1332 if (stub->is_constant()) { |
| 1352 IfBuilder builder(this); | 1333 IfBuilder builder(this); |
| 1353 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); | 1334 builder.If<HCompareObjectEqAndBranch>(cell_contents, value); |
| 1354 builder.Then(); | 1335 builder.Then(); |
| 1355 builder.ElseDeopt("Unexpected cell contents in constant global store"); | 1336 builder.ElseDeopt("Unexpected cell contents in constant global store"); |
| 1356 builder.End(); | 1337 builder.End(); |
| 1357 } else { | 1338 } else { |
| 1358 // Load the payload of the global parameter cell. A hole indicates that the | 1339 // Load the payload of the global parameter cell. A hole indicates that the |
| 1359 // property has been deleted and that the store must be handled by the | 1340 // property has been deleted and that the store must be handled by the |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 | 1418 |
| 1438 // TODO(fschneider): Idea: store proper code pointers in the optimized code | 1419 // TODO(fschneider): Idea: store proper code pointers in the optimized code |
| 1439 // map and either unmangle them on marking or do nothing as the whole map is | 1420 // map and either unmangle them on marking or do nothing as the whole map is |
| 1440 // discarded on major GC anyway. | 1421 // discarded on major GC anyway. |
| 1441 Add<HStoreCodeEntry>(js_function, code_object); | 1422 Add<HStoreCodeEntry>(js_function, code_object); |
| 1442 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), | 1423 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), |
| 1443 literals); | 1424 literals); |
| 1444 | 1425 |
| 1445 // Now link a function into a list of optimized functions. | 1426 // Now link a function into a list of optimized functions. |
| 1446 HValue* optimized_functions_list = Add<HLoadNamedField>( | 1427 HValue* optimized_functions_list = Add<HLoadNamedField>( |
| 1447 native_context, static_cast<HValue*>(NULL), | 1428 native_context, nullptr, |
| 1448 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); | 1429 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST)); |
| 1449 Add<HStoreNamedField>(js_function, | 1430 Add<HStoreNamedField>(js_function, |
| 1450 HObjectAccess::ForNextFunctionLinkPointer(), | 1431 HObjectAccess::ForNextFunctionLinkPointer(), |
| 1451 optimized_functions_list); | 1432 optimized_functions_list); |
| 1452 | 1433 |
| 1453 // This store is the only one that should have a write barrier. | 1434 // This store is the only one that should have a write barrier. |
| 1454 Add<HStoreNamedField>(native_context, | 1435 Add<HStoreNamedField>(native_context, |
| 1455 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), | 1436 HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST), |
| 1456 js_function); | 1437 js_function); |
| 1457 | 1438 |
| 1458 // The builder continues in the "then" after this function. | 1439 // The builder continues in the "then" after this function. |
| 1459 } | 1440 } |
| 1460 | 1441 |
| 1461 | 1442 |
| 1462 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, | 1443 void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function, |
| 1463 HValue* shared_info) { | 1444 HValue* shared_info) { |
| 1464 Add<HStoreNamedField>(js_function, | 1445 Add<HStoreNamedField>(js_function, |
| 1465 HObjectAccess::ForNextFunctionLinkPointer(), | 1446 HObjectAccess::ForNextFunctionLinkPointer(), |
| 1466 graph()->GetConstantUndefined()); | 1447 graph()->GetConstantUndefined()); |
| 1467 HValue* code_object = Add<HLoadNamedField>( | 1448 HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr, |
| 1468 shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset()); | 1449 HObjectAccess::ForCodeOffset()); |
| 1469 Add<HStoreCodeEntry>(js_function, code_object); | 1450 Add<HStoreCodeEntry>(js_function, code_object); |
| 1470 } | 1451 } |
| 1471 | 1452 |
| 1472 | 1453 |
| 1473 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap( | 1454 HInstruction* CodeStubGraphBuilderBase::LoadFromOptimizedCodeMap( |
| 1474 HValue* optimized_map, | 1455 HValue* optimized_map, |
| 1475 HValue* iterator, | 1456 HValue* iterator, |
| 1476 int field_offset) { | 1457 int field_offset) { |
| 1477 // By making sure to express these loads in the form [<hvalue> + constant] | 1458 // By making sure to express these loads in the form [<hvalue> + constant] |
| 1478 // the keyed load can be hoisted. | 1459 // the keyed load can be hoisted. |
| 1479 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength); | 1460 DCHECK(field_offset >= 0 && field_offset < SharedFunctionInfo::kEntryLength); |
| 1480 HValue* field_slot = iterator; | 1461 HValue* field_slot = iterator; |
| 1481 if (field_offset > 0) { | 1462 if (field_offset > 0) { |
| 1482 HValue* field_offset_value = Add<HConstant>(field_offset); | 1463 HValue* field_offset_value = Add<HConstant>(field_offset); |
| 1483 field_slot = AddUncasted<HAdd>(iterator, field_offset_value); | 1464 field_slot = AddUncasted<HAdd>(iterator, field_offset_value); |
| 1484 } | 1465 } |
| 1485 HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot, | 1466 HInstruction* field_entry = |
| 1486 static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1467 Add<HLoadKeyed>(optimized_map, field_slot, nullptr, FAST_ELEMENTS); |
| 1487 return field_entry; | 1468 return field_entry; |
| 1488 } | 1469 } |
| 1489 | 1470 |
| 1490 | 1471 |
| 1491 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( | 1472 void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap( |
| 1492 HValue* js_function, | 1473 HValue* js_function, |
| 1493 HValue* shared_info, | 1474 HValue* shared_info, |
| 1494 HValue* native_context) { | 1475 HValue* native_context) { |
| 1495 Counters* counters = isolate()->counters(); | 1476 Counters* counters = isolate()->counters(); |
| 1496 IfBuilder is_optimized(this); | 1477 IfBuilder is_optimized(this); |
| 1497 HInstruction* optimized_map = Add<HLoadNamedField>( | 1478 HInstruction* optimized_map = Add<HLoadNamedField>( |
| 1498 shared_info, static_cast<HValue*>(NULL), | 1479 shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap()); |
| 1499 HObjectAccess::ForOptimizedCodeMap()); | |
| 1500 HValue* null_constant = Add<HConstant>(0); | 1480 HValue* null_constant = Add<HConstant>(0); |
| 1501 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant); | 1481 is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant); |
| 1502 is_optimized.Then(); | 1482 is_optimized.Then(); |
| 1503 { | 1483 { |
| 1504 BuildInstallCode(js_function, shared_info); | 1484 BuildInstallCode(js_function, shared_info); |
| 1505 } | 1485 } |
| 1506 is_optimized.Else(); | 1486 is_optimized.Else(); |
| 1507 { | 1487 { |
| 1508 AddIncrementCounter(counters->fast_new_closure_try_optimized()); | 1488 AddIncrementCounter(counters->fast_new_closure_try_optimized()); |
| 1509 // optimized_map points to fixed array of 3-element entries | 1489 // optimized_map points to fixed array of 3-element entries |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1522 // for(i = map.length() - SharedFunctionInfo::kEntryLength; | 1502 // for(i = map.length() - SharedFunctionInfo::kEntryLength; |
| 1523 // i > SharedFunctionInfo::kEntriesStart; | 1503 // i > SharedFunctionInfo::kEntriesStart; |
| 1524 // i -= SharedFunctionInfo::kEntryLength) { .. } | 1504 // i -= SharedFunctionInfo::kEntryLength) { .. } |
| 1525 HValue* shared_function_entry_length = | 1505 HValue* shared_function_entry_length = |
| 1526 Add<HConstant>(SharedFunctionInfo::kEntryLength); | 1506 Add<HConstant>(SharedFunctionInfo::kEntryLength); |
| 1527 LoopBuilder loop_builder(this, | 1507 LoopBuilder loop_builder(this, |
| 1528 context(), | 1508 context(), |
| 1529 LoopBuilder::kPostDecrement, | 1509 LoopBuilder::kPostDecrement, |
| 1530 shared_function_entry_length); | 1510 shared_function_entry_length); |
| 1531 HValue* array_length = Add<HLoadNamedField>( | 1511 HValue* array_length = Add<HLoadNamedField>( |
| 1532 optimized_map, static_cast<HValue*>(NULL), | 1512 optimized_map, nullptr, HObjectAccess::ForFixedArrayLength()); |
| 1533 HObjectAccess::ForFixedArrayLength()); | |
| 1534 HValue* start_pos = AddUncasted<HSub>(array_length, | 1513 HValue* start_pos = AddUncasted<HSub>(array_length, |
| 1535 shared_function_entry_length); | 1514 shared_function_entry_length); |
| 1536 HValue* slot_iterator = loop_builder.BeginBody(start_pos, | 1515 HValue* slot_iterator = loop_builder.BeginBody(start_pos, |
| 1537 first_entry_index, | 1516 first_entry_index, |
| 1538 Token::GT); | 1517 Token::GT); |
| 1539 { | 1518 { |
| 1540 IfBuilder done_check(this); | 1519 IfBuilder done_check(this); |
| 1541 BuildCheckAndInstallOptimizedCode(js_function, native_context, | 1520 BuildCheckAndInstallOptimizedCode(js_function, native_context, |
| 1542 &done_check, | 1521 &done_check, |
| 1543 optimized_map, | 1522 optimized_map, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 HValue* size = Add<HConstant>(JSFunction::kSize); | 1555 HValue* size = Add<HConstant>(JSFunction::kSize); |
| 1577 HInstruction* js_function = | 1556 HInstruction* js_function = |
| 1578 Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE); | 1557 Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE); |
| 1579 | 1558 |
| 1580 int map_index = Context::FunctionMapIndex(casted_stub()->strict_mode(), | 1559 int map_index = Context::FunctionMapIndex(casted_stub()->strict_mode(), |
| 1581 casted_stub()->kind()); | 1560 casted_stub()->kind()); |
| 1582 | 1561 |
| 1583 // Compute the function map in the current native context and set that | 1562 // Compute the function map in the current native context and set that |
| 1584 // as the map of the allocated object. | 1563 // as the map of the allocated object. |
| 1585 HInstruction* native_context = BuildGetNativeContext(); | 1564 HInstruction* native_context = BuildGetNativeContext(); |
| 1586 HInstruction* map_slot_value = | 1565 HInstruction* map_slot_value = Add<HLoadNamedField>( |
| 1587 Add<HLoadNamedField>(native_context, static_cast<HValue*>(NULL), | 1566 native_context, nullptr, HObjectAccess::ForContextSlot(map_index)); |
| 1588 HObjectAccess::ForContextSlot(map_index)); | |
| 1589 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); | 1567 Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value); |
| 1590 | 1568 |
| 1591 // Initialize the rest of the function. | 1569 // Initialize the rest of the function. |
| 1592 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), | 1570 Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(), |
| 1593 empty_fixed_array); | 1571 empty_fixed_array); |
| 1594 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), | 1572 Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(), |
| 1595 empty_fixed_array); | 1573 empty_fixed_array); |
| 1596 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), | 1574 Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(), |
| 1597 empty_fixed_array); | 1575 empty_fixed_array); |
| 1598 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), | 1576 Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 function); | 1623 function); |
| 1646 Add<HStoreNamedField>(function_context, | 1624 Add<HStoreNamedField>(function_context, |
| 1647 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX), | 1625 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX), |
| 1648 context()); | 1626 context()); |
| 1649 Add<HStoreNamedField>(function_context, | 1627 Add<HStoreNamedField>(function_context, |
| 1650 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX), | 1628 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX), |
| 1651 graph()->GetConstant0()); | 1629 graph()->GetConstant0()); |
| 1652 | 1630 |
| 1653 // Copy the global object from the previous context. | 1631 // Copy the global object from the previous context. |
| 1654 HValue* global_object = Add<HLoadNamedField>( | 1632 HValue* global_object = Add<HLoadNamedField>( |
| 1655 context(), static_cast<HValue*>(NULL), | 1633 context(), nullptr, |
| 1656 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 1634 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 1657 Add<HStoreNamedField>(function_context, | 1635 Add<HStoreNamedField>(function_context, |
| 1658 HObjectAccess::ForContextSlot( | 1636 HObjectAccess::ForContextSlot( |
| 1659 Context::GLOBAL_OBJECT_INDEX), | 1637 Context::GLOBAL_OBJECT_INDEX), |
| 1660 global_object); | 1638 global_object); |
| 1661 | 1639 |
| 1662 // Initialize the rest of the slots to undefined. | 1640 // Initialize the rest of the slots to undefined. |
| 1663 for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) { | 1641 for (int i = Context::MIN_CONTEXT_SLOTS; i < length; ++i) { |
| 1664 Add<HStoreNamedField>(function_context, | 1642 Add<HStoreNamedField>(function_context, |
| 1665 HObjectAccess::ForContextSlot(i), | 1643 HObjectAccess::ForContextSlot(i), |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1810 IfBuilder index_name_split(this, &index_name_split_continuation); | 1788 IfBuilder index_name_split(this, &index_name_split_continuation); |
| 1811 index_name_split.Then(); | 1789 index_name_split.Then(); |
| 1812 { | 1790 { |
| 1813 // Key is an index (number) | 1791 // Key is an index (number) |
| 1814 key = Pop(); | 1792 key = Pop(); |
| 1815 | 1793 |
| 1816 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) | | 1794 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) | |
| 1817 (1 << Map::kHasIndexedInterceptor); | 1795 (1 << Map::kHasIndexedInterceptor); |
| 1818 BuildJSObjectCheck(receiver, bit_field_mask); | 1796 BuildJSObjectCheck(receiver, bit_field_mask); |
| 1819 | 1797 |
| 1820 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 1798 HValue* map = |
| 1821 HObjectAccess::ForMap()); | 1799 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 1822 | 1800 |
| 1823 HValue* instance_type = | 1801 HValue* instance_type = |
| 1824 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), | 1802 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 1825 HObjectAccess::ForMapInstanceType()); | |
| 1826 | 1803 |
| 1827 HValue* bit_field2 = Add<HLoadNamedField>(map, | 1804 HValue* bit_field2 = |
| 1828 static_cast<HValue*>(NULL), | 1805 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); |
| 1829 HObjectAccess::ForMapBitField2()); | |
| 1830 | 1806 |
| 1831 IfBuilder kind_if(this); | 1807 IfBuilder kind_if(this); |
| 1832 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | 1808 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2, |
| 1833 FAST_HOLEY_ELEMENTS); | 1809 FAST_HOLEY_ELEMENTS); |
| 1834 | 1810 |
| 1835 kind_if.Else(); | 1811 kind_if.Else(); |
| 1836 { | 1812 { |
| 1837 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2, | 1813 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2, |
| 1838 FAST_HOLEY_DOUBLE_ELEMENTS); | 1814 FAST_HOLEY_DOUBLE_ELEMENTS); |
| 1839 } | 1815 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 | 1885 |
| 1910 HIfContinuation continuation; | 1886 HIfContinuation continuation; |
| 1911 BuildTestForDictionaryProperties(receiver, &continuation); | 1887 BuildTestForDictionaryProperties(receiver, &continuation); |
| 1912 IfBuilder if_dict_properties(this, &continuation); | 1888 IfBuilder if_dict_properties(this, &continuation); |
| 1913 if_dict_properties.Then(); | 1889 if_dict_properties.Then(); |
| 1914 { | 1890 { |
| 1915 // Key is string, properties are dictionary mode | 1891 // Key is string, properties are dictionary mode |
| 1916 BuildNonGlobalObjectCheck(receiver); | 1892 BuildNonGlobalObjectCheck(receiver); |
| 1917 | 1893 |
| 1918 HValue* properties = Add<HLoadNamedField>( | 1894 HValue* properties = Add<HLoadNamedField>( |
| 1919 receiver, static_cast<HValue*>(NULL), | 1895 receiver, nullptr, HObjectAccess::ForPropertiesPointer()); |
| 1920 HObjectAccess::ForPropertiesPointer()); | |
| 1921 | 1896 |
| 1922 HValue* hash = | 1897 HValue* hash = |
| 1923 Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), | 1898 Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForNameHashField()); |
| 1924 HObjectAccess::ForNameHashField()); | |
| 1925 | 1899 |
| 1926 hash = AddUncasted<HShr>(hash, Add<HConstant>(Name::kHashShift)); | 1900 hash = AddUncasted<HShr>(hash, Add<HConstant>(Name::kHashShift)); |
| 1927 | 1901 |
| 1928 HValue* value = BuildUncheckedDictionaryElementLoad(receiver, | 1902 HValue* value = BuildUncheckedDictionaryElementLoad(receiver, |
| 1929 properties, | 1903 properties, |
| 1930 key, | 1904 key, |
| 1931 hash); | 1905 hash); |
| 1932 Push(value); | 1906 Push(value); |
| 1933 } | 1907 } |
| 1934 if_dict_properties.Else(); | 1908 if_dict_properties.Else(); |
| 1935 { | 1909 { |
| 1936 // Key is string, properties are fast mode | 1910 // Key is string, properties are fast mode |
| 1937 HValue* hash = BuildKeyedLookupCacheHash(receiver, key); | 1911 HValue* hash = BuildKeyedLookupCacheHash(receiver, key); |
| 1938 | 1912 |
| 1939 ExternalReference cache_keys_ref = | 1913 ExternalReference cache_keys_ref = |
| 1940 ExternalReference::keyed_lookup_cache_keys(isolate()); | 1914 ExternalReference::keyed_lookup_cache_keys(isolate()); |
| 1941 HValue* cache_keys = Add<HConstant>(cache_keys_ref); | 1915 HValue* cache_keys = Add<HConstant>(cache_keys_ref); |
| 1942 | 1916 |
| 1943 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 1917 HValue* map = |
| 1944 HObjectAccess::ForMap()); | 1918 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 1945 HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2)); | 1919 HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2)); |
| 1946 base_index->ClearFlag(HValue::kCanOverflow); | 1920 base_index->ClearFlag(HValue::kCanOverflow); |
| 1947 | 1921 |
| 1948 HIfContinuation inline_or_runtime_continuation( | 1922 HIfContinuation inline_or_runtime_continuation( |
| 1949 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | 1923 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); |
| 1950 { | 1924 { |
| 1951 IfBuilder lookup_ifs[KeyedLookupCache::kEntriesPerBucket]; | 1925 IfBuilder lookup_ifs[KeyedLookupCache::kEntriesPerBucket]; |
| 1952 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket; | 1926 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket; |
| 1953 ++probe) { | 1927 ++probe) { |
| 1954 IfBuilder* lookup_if = &lookup_ifs[probe]; | 1928 IfBuilder* lookup_if = &lookup_ifs[probe]; |
| 1955 lookup_if->Initialize(this); | 1929 lookup_if->Initialize(this); |
| 1956 int probe_base = probe * KeyedLookupCache::kEntryLength; | 1930 int probe_base = probe * KeyedLookupCache::kEntryLength; |
| 1957 HValue* map_index = AddUncasted<HAdd>( | 1931 HValue* map_index = AddUncasted<HAdd>( |
| 1958 base_index, | 1932 base_index, |
| 1959 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); | 1933 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); |
| 1960 map_index->ClearFlag(HValue::kCanOverflow); | 1934 map_index->ClearFlag(HValue::kCanOverflow); |
| 1961 HValue* key_index = AddUncasted<HAdd>( | 1935 HValue* key_index = AddUncasted<HAdd>( |
| 1962 base_index, | 1936 base_index, |
| 1963 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); | 1937 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); |
| 1964 key_index->ClearFlag(HValue::kCanOverflow); | 1938 key_index->ClearFlag(HValue::kCanOverflow); |
| 1965 HValue* map_to_check = | 1939 HValue* map_to_check = |
| 1966 Add<HLoadKeyed>(cache_keys, map_index, static_cast<HValue*>(NULL), | 1940 Add<HLoadKeyed>(cache_keys, map_index, nullptr, FAST_ELEMENTS, |
| 1967 FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); | 1941 NEVER_RETURN_HOLE, 0); |
| 1968 lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map); | 1942 lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map); |
| 1969 lookup_if->And(); | 1943 lookup_if->And(); |
| 1970 HValue* key_to_check = | 1944 HValue* key_to_check = |
| 1971 Add<HLoadKeyed>(cache_keys, key_index, static_cast<HValue*>(NULL), | 1945 Add<HLoadKeyed>(cache_keys, key_index, nullptr, FAST_ELEMENTS, |
| 1972 FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); | 1946 NEVER_RETURN_HOLE, 0); |
| 1973 lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key); | 1947 lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key); |
| 1974 lookup_if->Then(); | 1948 lookup_if->Then(); |
| 1975 { | 1949 { |
| 1976 ExternalReference cache_field_offsets_ref = | 1950 ExternalReference cache_field_offsets_ref = |
| 1977 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); | 1951 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); |
| 1978 HValue* cache_field_offsets = | 1952 HValue* cache_field_offsets = |
| 1979 Add<HConstant>(cache_field_offsets_ref); | 1953 Add<HConstant>(cache_field_offsets_ref); |
| 1980 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); | 1954 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); |
| 1981 index->ClearFlag(HValue::kCanOverflow); | 1955 index->ClearFlag(HValue::kCanOverflow); |
| 1982 HValue* property_index = Add<HLoadKeyed>( | 1956 HValue* property_index = |
| 1983 cache_field_offsets, index, static_cast<HValue*>(NULL), | 1957 Add<HLoadKeyed>(cache_field_offsets, index, nullptr, |
| 1984 EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); | 1958 EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); |
| 1985 Push(property_index); | 1959 Push(property_index); |
| 1986 } | 1960 } |
| 1987 lookup_if->Else(); | 1961 lookup_if->Else(); |
| 1988 } | 1962 } |
| 1989 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { | 1963 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { |
| 1990 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); | 1964 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); |
| 1991 } | 1965 } |
| 1992 } | 1966 } |
| 1993 | 1967 |
| 1994 IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation); | 1968 IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2020 } | 1994 } |
| 2021 | 1995 |
| 2022 | 1996 |
| 2023 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name, | 1997 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name, |
| 2024 HValue* array, HValue* map_index, | 1998 HValue* array, HValue* map_index, |
| 2025 HValue* slot, HValue* vector) { | 1999 HValue* slot, HValue* vector) { |
| 2026 // The handler is at array[map_index + 1]. Compute this with a custom offset | 2000 // The handler is at array[map_index + 1]. Compute this with a custom offset |
| 2027 // to HLoadKeyed. | 2001 // to HLoadKeyed. |
| 2028 int offset = | 2002 int offset = |
| 2029 GetDefaultHeaderSizeForElementsKind(FAST_ELEMENTS) + kPointerSize; | 2003 GetDefaultHeaderSizeForElementsKind(FAST_ELEMENTS) + kPointerSize; |
| 2030 HValue* handler_code = | 2004 HValue* handler_code = Add<HLoadKeyed>( |
| 2031 Add<HLoadKeyed>(array, map_index, static_cast<HValue*>(NULL), | 2005 array, map_index, nullptr, FAST_ELEMENTS, NEVER_RETURN_HOLE, offset); |
| 2032 FAST_ELEMENTS, NEVER_RETURN_HOLE, offset); | |
| 2033 TailCallHandler(receiver, name, slot, vector, handler_code); | 2006 TailCallHandler(receiver, name, slot, vector, handler_code); |
| 2034 } | 2007 } |
| 2035 | 2008 |
| 2036 | 2009 |
| 2037 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name, | 2010 void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name, |
| 2038 HValue* slot, HValue* vector, | 2011 HValue* slot, HValue* vector, |
| 2039 HValue* handler_code) { | 2012 HValue* handler_code) { |
| 2040 VectorLoadICDescriptor descriptor(isolate()); | 2013 VectorLoadICDescriptor descriptor(isolate()); |
| 2041 HValue* op_vals[] = {context(), receiver, name, slot, vector}; | 2014 HValue* op_vals[] = {context(), receiver, name, slot, vector}; |
| 2042 Add<HCallWithDescriptor>(handler_code, 0, descriptor, | 2015 Add<HCallWithDescriptor>(handler_code, 0, descriptor, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2060 HValue* name, HValue* slot, | 2033 HValue* name, HValue* slot, |
| 2061 HValue* vector, | 2034 HValue* vector, |
| 2062 bool keyed_load) { | 2035 bool keyed_load) { |
| 2063 IfBuilder if_receiver_heap_object(this); | 2036 IfBuilder if_receiver_heap_object(this); |
| 2064 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver); | 2037 if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver); |
| 2065 if_receiver_heap_object.Then(); | 2038 if_receiver_heap_object.Then(); |
| 2066 { | 2039 { |
| 2067 HConstant* constant_two = Add<HConstant>(2); | 2040 HConstant* constant_two = Add<HConstant>(2); |
| 2068 HConstant* constant_three = Add<HConstant>(3); | 2041 HConstant* constant_three = Add<HConstant>(3); |
| 2069 | 2042 |
| 2070 HValue* receiver_map = AddLoadMap(receiver, static_cast<HValue*>(NULL)); | 2043 HValue* receiver_map = AddLoadMap(receiver, nullptr); |
| 2071 HValue* start = | 2044 HValue* start = |
| 2072 keyed_load ? graph()->GetConstant1() : graph()->GetConstant0(); | 2045 keyed_load ? graph()->GetConstant1() : graph()->GetConstant0(); |
| 2073 HValue* array_map = | 2046 HValue* array_map = Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS, |
| 2074 Add<HLoadKeyed>(array, start, static_cast<HValue*>(NULL), FAST_ELEMENTS, | 2047 ALLOW_RETURN_HOLE); |
| 2075 ALLOW_RETURN_HOLE); | |
| 2076 IfBuilder if_correct_map(this); | 2048 IfBuilder if_correct_map(this); |
| 2077 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map); | 2049 if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map); |
| 2078 if_correct_map.Then(); | 2050 if_correct_map.Then(); |
| 2079 { TailCallHandler(receiver, name, array, start, slot, vector); } | 2051 { TailCallHandler(receiver, name, array, start, slot, vector); } |
| 2080 if_correct_map.Else(); | 2052 if_correct_map.Else(); |
| 2081 { | 2053 { |
| 2082 // If our array has more elements, the ic is polymorphic. Look for the | 2054 // If our array has more elements, the ic is polymorphic. Look for the |
| 2083 // receiver map in the rest of the array. | 2055 // receiver map in the rest of the array. |
| 2084 HValue* length = | 2056 HValue* length = AddLoadFixedArrayLength(array, nullptr); |
| 2085 AddLoadFixedArrayLength(array, static_cast<HValue*>(NULL)); | |
| 2086 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement, | 2057 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement, |
| 2087 constant_two); | 2058 constant_two); |
| 2088 start = keyed_load ? constant_three : constant_two; | 2059 start = keyed_load ? constant_three : constant_two; |
| 2089 HValue* key = builder.BeginBody(start, length, Token::LT); | 2060 HValue* key = builder.BeginBody(start, length, Token::LT); |
| 2090 { | 2061 { |
| 2091 HValue* array_map = | 2062 HValue* array_map = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS, |
| 2092 Add<HLoadKeyed>(array, key, static_cast<HValue*>(NULL), | 2063 ALLOW_RETURN_HOLE); |
| 2093 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
| 2094 IfBuilder if_correct_poly_map(this); | 2064 IfBuilder if_correct_poly_map(this); |
| 2095 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map, | 2065 if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map, |
| 2096 array_map); | 2066 array_map); |
| 2097 if_correct_poly_map.Then(); | 2067 if_correct_poly_map.Then(); |
| 2098 { TailCallHandler(receiver, name, array, key, slot, vector); } | 2068 { TailCallHandler(receiver, name, array, key, slot, vector); } |
| 2099 } | 2069 } |
| 2100 builder.EndBody(); | 2070 builder.EndBody(); |
| 2101 } | 2071 } |
| 2102 if_correct_map.End(); | 2072 if_correct_map.End(); |
| 2103 } | 2073 } |
| 2104 } | 2074 } |
| 2105 | 2075 |
| 2106 | 2076 |
| 2107 template <> | 2077 template <> |
| 2108 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() { | 2078 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() { |
| 2109 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); | 2079 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); |
| 2110 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex); | 2080 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex); |
| 2111 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex); | 2081 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex); |
| 2112 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex); | 2082 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex); |
| 2113 | 2083 |
| 2114 // If the feedback is an array, then the IC is in the monomorphic or | 2084 // If the feedback is an array, then the IC is in the monomorphic or |
| 2115 // polymorphic state. | 2085 // polymorphic state. |
| 2116 HValue* feedback = Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL), | 2086 HValue* feedback = |
| 2117 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 2087 Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 2118 IfBuilder array_checker(this); | 2088 IfBuilder array_checker(this); |
| 2119 array_checker.If<HCompareMap>(feedback, | 2089 array_checker.If<HCompareMap>(feedback, |
| 2120 isolate()->factory()->fixed_array_map()); | 2090 isolate()->factory()->fixed_array_map()); |
| 2121 array_checker.Then(); | 2091 array_checker.Then(); |
| 2122 { HandleArrayCases(feedback, receiver, name, slot, vector, false); } | 2092 { HandleArrayCases(feedback, receiver, name, slot, vector, false); } |
| 2123 array_checker.Else(); | 2093 array_checker.Else(); |
| 2124 { | 2094 { |
| 2125 // Is the IC megamorphic? | 2095 // Is the IC megamorphic? |
| 2126 IfBuilder mega_checker(this); | 2096 IfBuilder mega_checker(this); |
| 2127 HConstant* megamorphic_symbol = | 2097 HConstant* megamorphic_symbol = |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2149 template <> | 2119 template <> |
| 2150 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() { | 2120 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() { |
| 2151 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); | 2121 HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex); |
| 2152 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex); | 2122 HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex); |
| 2153 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex); | 2123 HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex); |
| 2154 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex); | 2124 HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex); |
| 2155 HConstant* zero = graph()->GetConstant0(); | 2125 HConstant* zero = graph()->GetConstant0(); |
| 2156 | 2126 |
| 2157 // If the feedback is an array, then the IC is in the monomorphic or | 2127 // If the feedback is an array, then the IC is in the monomorphic or |
| 2158 // polymorphic state. | 2128 // polymorphic state. |
| 2159 HValue* feedback = Add<HLoadKeyed>(vector, slot, static_cast<HValue*>(NULL), | 2129 HValue* feedback = |
| 2160 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 2130 Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 2161 IfBuilder array_checker(this); | 2131 IfBuilder array_checker(this); |
| 2162 array_checker.If<HCompareMap>(feedback, | 2132 array_checker.If<HCompareMap>(feedback, |
| 2163 isolate()->factory()->fixed_array_map()); | 2133 isolate()->factory()->fixed_array_map()); |
| 2164 array_checker.Then(); | 2134 array_checker.Then(); |
| 2165 { | 2135 { |
| 2166 // If feedback[0] is 0, then the IC has element handlers and name should be | 2136 // If feedback[0] is 0, then the IC has element handlers and name should be |
| 2167 // a smi. If feedback[0] is a string, verify that it matches name. | 2137 // a smi. If feedback[0] is a string, verify that it matches name. |
| 2168 HValue* recorded_name = | 2138 HValue* recorded_name = Add<HLoadKeyed>(feedback, zero, nullptr, |
| 2169 Add<HLoadKeyed>(feedback, zero, static_cast<HValue*>(NULL), | 2139 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 2170 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | |
| 2171 | 2140 |
| 2172 IfBuilder recorded_name_is_zero(this); | 2141 IfBuilder recorded_name_is_zero(this); |
| 2173 recorded_name_is_zero.If<HCompareObjectEqAndBranch>(recorded_name, zero); | 2142 recorded_name_is_zero.If<HCompareObjectEqAndBranch>(recorded_name, zero); |
| 2174 recorded_name_is_zero.Then(); | 2143 recorded_name_is_zero.Then(); |
| 2175 { Add<HCheckSmi>(name); } | 2144 { Add<HCheckSmi>(name); } |
| 2176 recorded_name_is_zero.Else(); | 2145 recorded_name_is_zero.Else(); |
| 2177 { | 2146 { |
| 2178 IfBuilder strings_match(this); | 2147 IfBuilder strings_match(this); |
| 2179 strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name); | 2148 strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name); |
| 2180 strings_match.Then(); | 2149 strings_match.Then(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2231 // megamorphic case is handled as part of the default stub. | 2200 // megamorphic case is handled as part of the default stub. |
| 2232 DCHECK(!FLAG_vector_ics); | 2201 DCHECK(!FLAG_vector_ics); |
| 2233 | 2202 |
| 2234 // Probe the stub cache. | 2203 // Probe the stub cache. |
| 2235 Add<HTailCallThroughMegamorphicCache>(receiver, name); | 2204 Add<HTailCallThroughMegamorphicCache>(receiver, name); |
| 2236 | 2205 |
| 2237 // We never continue. | 2206 // We never continue. |
| 2238 return graph()->GetConstant0(); | 2207 return graph()->GetConstant0(); |
| 2239 } | 2208 } |
| 2240 } } // namespace v8::internal | 2209 } } // namespace v8::internal |
| OLD | NEW |