Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 2369933005: Speedup global_proxy.* attributes/accessors (specialize GlobalProxy access). (Closed)
Patch Set: Merge cached accessors + global proxy specialization Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/ic/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/crankshaft/hydrogen.h" 5 #include "src/crankshaft/hydrogen.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/allocation-site-scopes.h" 10 #include "src/allocation-site-scopes.h"
(...skipping 5430 matching lines...) Expand 10 before | Expand all | Expand 10 after
5441 5441
5442 if (!ast_context()->IsTest()) { 5442 if (!ast_context()->IsTest()) {
5443 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 5443 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
5444 set_current_block(join); 5444 set_current_block(join);
5445 if (join != NULL && !ast_context()->IsEffect()) { 5445 if (join != NULL && !ast_context()->IsEffect()) {
5446 return ast_context()->ReturnValue(Pop()); 5446 return ast_context()->ReturnValue(Pop());
5447 } 5447 }
5448 } 5448 }
5449 } 5449 }
5450 5450
5451 bool HOptimizedGraphBuilder::CanInlineGlobalPropertyAccess(
5452 Variable* var, LookupIterator* it, PropertyAccessType access_type) {
5453 if (var->is_this()) return false;
5454 return CanInlineGlobalPropertyAccess(it, access_type);
5455 }
5451 5456
5452 HOptimizedGraphBuilder::GlobalPropertyAccess 5457 bool HOptimizedGraphBuilder::CanInlineGlobalPropertyAccess(
5453 HOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it, 5458 LookupIterator* it, PropertyAccessType access_type) {
5454 PropertyAccessType access_type) { 5459 if (!current_info()->has_global_object()) {
5455 if (var->is_this() || !current_info()->has_global_object()) { 5460 return false;
5456 return kUseGeneric;
5457 } 5461 }
5458 5462
5459 switch (it->state()) { 5463 switch (it->state()) {
5460 case LookupIterator::ACCESSOR: 5464 case LookupIterator::ACCESSOR:
5461 case LookupIterator::ACCESS_CHECK: 5465 case LookupIterator::ACCESS_CHECK:
5462 case LookupIterator::INTERCEPTOR: 5466 case LookupIterator::INTERCEPTOR:
5463 case LookupIterator::INTEGER_INDEXED_EXOTIC: 5467 case LookupIterator::INTEGER_INDEXED_EXOTIC:
5464 case LookupIterator::NOT_FOUND: 5468 case LookupIterator::NOT_FOUND:
5465 return kUseGeneric; 5469 return false;
5466 case LookupIterator::DATA: 5470 case LookupIterator::DATA:
5467 if (access_type == STORE && it->IsReadOnly()) return kUseGeneric; 5471 if (access_type == STORE && it->IsReadOnly()) return false;
5468 if (!it->GetHolder<JSObject>()->IsJSGlobalObject()) return kUseGeneric; 5472 if (!it->GetHolder<JSObject>()->IsJSGlobalObject()) return false;
5469 return kUseCell; 5473 return true;
5470 case LookupIterator::JSPROXY: 5474 case LookupIterator::JSPROXY:
5471 case LookupIterator::TRANSITION: 5475 case LookupIterator::TRANSITION:
5472 UNREACHABLE(); 5476 UNREACHABLE();
5473 } 5477 }
5474 UNREACHABLE(); 5478 UNREACHABLE();
5475 return kUseGeneric; 5479 return false;
5476 } 5480 }
5477 5481
5478 5482
5479 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 5483 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
5480 DCHECK(var->IsContextSlot()); 5484 DCHECK(var->IsContextSlot());
5481 HValue* context = environment()->context(); 5485 HValue* context = environment()->context();
5482 int length = scope()->ContextChainLength(var->scope()); 5486 int length = scope()->ContextChainLength(var->scope());
5483 while (length-- > 0) { 5487 while (length-- > 0) {
5484 context = Add<HLoadNamedField>( 5488 context = Add<HLoadNamedField>(
5485 context, nullptr, 5489 context, nullptr,
5486 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 5490 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
5487 } 5491 }
5488 return context; 5492 return context;
5489 } 5493 }
5490 5494
5495 LookupIterator TryReadingFromCache(Isolate* isolate, LookupIterator* it) {
5496 if (it->state() != LookupIterator::ACCESSOR) return *it;
5497
5498 Handle<Object> accessors = it->GetAccessors();
5499 if (!accessors->IsAccessorPair()) return *it;
5500
5501 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
5502 isolate);
5503
5504 MaybeHandle<Name> maybe_name =
5505 FunctionTemplateInfo::TryGetCachePropertyName(isolate, getter);
5506 if (maybe_name.is_null()) return *it;
5507
5508 Handle<Name> name = maybe_name.ToHandleChecked();
5509 LookupIterator cache_it(it->GetReceiver(), name, it->GetHolder<JSObject>());
5510 CHECK_EQ(cache_it.state(), LookupIterator::DATA);
5511 return cache_it;
5512 }
5513
5514 void HOptimizedGraphBuilder::InlineGlobalPropertyLoad(LookupIterator* it,
5515 BailoutId ast_id) {
5516 Handle<PropertyCell> cell = it->GetPropertyCell();
5517 top_info()->dependencies()->AssumePropertyCell(cell);
5518 auto cell_type = it->property_details().cell_type();
5519 if (cell_type == PropertyCellType::kConstant ||
5520 cell_type == PropertyCellType::kUndefined) {
5521 Handle<Object> constant_object(cell->value(), isolate());
5522 if (constant_object->IsConsString()) {
5523 constant_object = String::Flatten(Handle<String>::cast(constant_object));
5524 }
5525 HConstant* constant = New<HConstant>(constant_object);
5526 return ast_context()->ReturnInstruction(constant, ast_id);
5527 } else {
5528 auto access = HObjectAccess::ForPropertyCellValue();
5529 UniqueSet<Map>* field_maps = nullptr;
5530 if (cell_type == PropertyCellType::kConstantType) {
5531 switch (cell->GetConstantType()) {
5532 case PropertyCellConstantType::kSmi:
5533 access = access.WithRepresentation(Representation::Smi());
5534 break;
5535 case PropertyCellConstantType::kStableMap: {
5536 // Check that the map really is stable. The heap object could
5537 // have mutated without the cell updating state. In that case,
5538 // make no promises about the loaded value except that it's a
5539 // heap object.
5540 access = access.WithRepresentation(Representation::HeapObject());
5541 Handle<Map> map(HeapObject::cast(cell->value())->map());
5542 if (map->is_stable()) {
5543 field_maps = new (zone())
5544 UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone());
5545 }
5546 break;
5547 }
5548 }
5549 }
5550 HConstant* cell_constant = Add<HConstant>(cell);
5551 HLoadNamedField* instr;
5552 if (field_maps == nullptr) {
5553 instr = New<HLoadNamedField>(cell_constant, nullptr, access);
5554 } else {
5555 instr = New<HLoadNamedField>(cell_constant, nullptr, access, field_maps,
5556 HType::HeapObject());
5557 }
5558 instr->ClearDependsOnFlag(kInobjectFields);
5559 instr->SetDependsOnFlag(kGlobalVars);
5560 return ast_context()->ReturnInstruction(instr, ast_id);
5561 }
5562 }
5491 5563
5492 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 5564 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
5493 DCHECK(!HasStackOverflow()); 5565 DCHECK(!HasStackOverflow());
5494 DCHECK(current_block() != NULL); 5566 DCHECK(current_block() != NULL);
5495 DCHECK(current_block()->HasPredecessor()); 5567 DCHECK(current_block()->HasPredecessor());
5496 Variable* variable = expr->var(); 5568 Variable* variable = expr->var();
5497 switch (variable->location()) { 5569 switch (variable->location()) {
5498 case VariableLocation::UNALLOCATED: { 5570 case VariableLocation::UNALLOCATED: {
5499 if (IsLexicalVariableMode(variable->mode())) { 5571 if (IsLexicalVariableMode(variable->mode())) {
5500 // TODO(rossberg): should this be an DCHECK? 5572 // TODO(rossberg): should this be an DCHECK?
(...skipping 27 matching lines...) Expand all
5528 if (current_value->IsTheHole(isolate())) { 5600 if (current_value->IsTheHole(isolate())) {
5529 return Bailout(kReferenceToUninitializedVariable); 5601 return Bailout(kReferenceToUninitializedVariable);
5530 } 5602 }
5531 HInstruction* result = New<HLoadNamedField>( 5603 HInstruction* result = New<HLoadNamedField>(
5532 Add<HConstant>(script_context), nullptr, 5604 Add<HConstant>(script_context), nullptr,
5533 HObjectAccess::ForContextSlot(lookup.slot_index)); 5605 HObjectAccess::ForContextSlot(lookup.slot_index));
5534 return ast_context()->ReturnInstruction(result, expr->id()); 5606 return ast_context()->ReturnInstruction(result, expr->id());
5535 } 5607 }
5536 } 5608 }
5537 5609
5538 LookupIterator it(global, variable->name(), LookupIterator::OWN); 5610 LookupIterator default_it(global, variable->name(), LookupIterator::OWN);
5539 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); 5611 LookupIterator it = TryReadingFromCache(isolate(), &default_it);
5540 5612 if (CanInlineGlobalPropertyAccess(variable, &it, LOAD)) {
5541 if (type == kUseCell) { 5613 InlineGlobalPropertyLoad(&it, expr->id());
5542 Handle<PropertyCell> cell = it.GetPropertyCell(); 5614 return;
5543 top_info()->dependencies()->AssumePropertyCell(cell);
5544 auto cell_type = it.property_details().cell_type();
5545 if (cell_type == PropertyCellType::kConstant ||
5546 cell_type == PropertyCellType::kUndefined) {
5547 Handle<Object> constant_object(cell->value(), isolate());
5548 if (constant_object->IsConsString()) {
5549 constant_object =
5550 String::Flatten(Handle<String>::cast(constant_object));
5551 }
5552 HConstant* constant = New<HConstant>(constant_object);
5553 return ast_context()->ReturnInstruction(constant, expr->id());
5554 } else {
5555 auto access = HObjectAccess::ForPropertyCellValue();
5556 UniqueSet<Map>* field_maps = nullptr;
5557 if (cell_type == PropertyCellType::kConstantType) {
5558 switch (cell->GetConstantType()) {
5559 case PropertyCellConstantType::kSmi:
5560 access = access.WithRepresentation(Representation::Smi());
5561 break;
5562 case PropertyCellConstantType::kStableMap: {
5563 // Check that the map really is stable. The heap object could
5564 // have mutated without the cell updating state. In that case,
5565 // make no promises about the loaded value except that it's a
5566 // heap object.
5567 access =
5568 access.WithRepresentation(Representation::HeapObject());
5569 Handle<Map> map(HeapObject::cast(cell->value())->map());
5570 if (map->is_stable()) {
5571 field_maps = new (zone())
5572 UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone());
5573 }
5574 break;
5575 }
5576 }
5577 }
5578 HConstant* cell_constant = Add<HConstant>(cell);
5579 HLoadNamedField* instr;
5580 if (field_maps == nullptr) {
5581 instr = New<HLoadNamedField>(cell_constant, nullptr, access);
5582 } else {
5583 instr = New<HLoadNamedField>(cell_constant, nullptr, access,
5584 field_maps, HType::HeapObject());
5585 }
5586 instr->ClearDependsOnFlag(kInobjectFields);
5587 instr->SetDependsOnFlag(kGlobalVars);
5588 return ast_context()->ReturnInstruction(instr, expr->id());
5589 }
5590 } else { 5615 } else {
5591 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); 5616 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
5592 HLoadGlobalGeneric* instr = New<HLoadGlobalGeneric>( 5617 HLoadGlobalGeneric* instr = New<HLoadGlobalGeneric>(
5593 variable->name(), ast_context()->typeof_mode(), vector, 5618 variable->name(), ast_context()->typeof_mode(), vector,
5594 expr->VariableFeedbackSlot()); 5619 expr->VariableFeedbackSlot());
5595 return ast_context()->ReturnInstruction(instr, expr->id()); 5620 return ast_context()->ReturnInstruction(instr, expr->id());
5596 } 5621 }
5597 } 5622 }
5598 5623
5599 case VariableLocation::PARAMETER: 5624 case VariableLocation::PARAMETER:
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
6380 return BuildStoreNamedField(info, checked_object, value); 6405 return BuildStoreNamedField(info, checked_object, value);
6381 } 6406 }
6382 } 6407 }
6383 6408
6384 if (info->IsTransition()) { 6409 if (info->IsTransition()) {
6385 DCHECK(!info->IsLoad()); 6410 DCHECK(!info->IsLoad());
6386 return BuildStoreNamedField(info, checked_object, value); 6411 return BuildStoreNamedField(info, checked_object, value);
6387 } 6412 }
6388 6413
6389 if (info->IsAccessorConstant()) { 6414 if (info->IsAccessorConstant()) {
6415 MaybeHandle<Name> maybe_name =
6416 FunctionTemplateInfo::TryGetCachePropertyName(isolate(),
6417 info->accessor());
6418 if (!maybe_name.is_null()) {
6419 Handle<Name> name = maybe_name.ToHandleChecked();
6420 PropertyAccessInfo cache_info(this, LOAD, info->map(), name);
6421 // Load new target.
6422 if (cache_info.CanAccessMonomorphic())
6423 return BuildLoadNamedField(&cache_info, checked_object);
6424 }
6425
6390 Push(checked_object); 6426 Push(checked_object);
6391 int argument_count = 1; 6427 int argument_count = 1;
6392 if (!info->IsLoad()) { 6428 if (!info->IsLoad()) {
6393 argument_count = 2; 6429 argument_count = 2;
6394 Push(value); 6430 Push(value);
6395 } 6431 }
6396 6432
6397 if (info->accessor()->IsJSFunction() && 6433 if (info->accessor()->IsJSFunction() &&
6398 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) { 6434 info->NeedsWrappingFor(Handle<JSFunction>::cast(info->accessor()))) {
6399 HValue* function = Add<HConstant>(info->accessor()); 6435 HValue* function = Add<HConstant>(info->accessor());
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
6675 DCHECK(prop != NULL); 6711 DCHECK(prop != NULL);
6676 CHECK_ALIVE(VisitForValue(prop->obj())); 6712 CHECK_ALIVE(VisitForValue(prop->obj()));
6677 if (!prop->key()->IsPropertyName()) { 6713 if (!prop->key()->IsPropertyName()) {
6678 CHECK_ALIVE(VisitForValue(prop->key())); 6714 CHECK_ALIVE(VisitForValue(prop->key()));
6679 } 6715 }
6680 CHECK_ALIVE(VisitForValue(expr->value())); 6716 CHECK_ALIVE(VisitForValue(expr->value()));
6681 BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), 6717 BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(),
6682 expr->AssignmentId(), expr->IsUninitialized()); 6718 expr->AssignmentId(), expr->IsUninitialized());
6683 } 6719 }
6684 6720
6721 void HOptimizedGraphBuilder::InlineGlobalPropertyStore(LookupIterator* it,
6722 HValue* value,
6723 BailoutId ast_id) {
6724 Handle<PropertyCell> cell = it->GetPropertyCell();
6725 top_info()->dependencies()->AssumePropertyCell(cell);
6726 auto cell_type = it->property_details().cell_type();
6727 if (cell_type == PropertyCellType::kConstant ||
6728 cell_type == PropertyCellType::kUndefined) {
6729 Handle<Object> constant(cell->value(), isolate());
6730 if (value->IsConstant()) {
6731 HConstant* c_value = HConstant::cast(value);
6732 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6733 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6734 Deoptimizer::EAGER);
6735 }
6736 } else {
6737 HValue* c_constant = Add<HConstant>(constant);
6738 IfBuilder builder(this);
6739 if (constant->IsNumber()) {
6740 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ);
6741 } else {
6742 builder.If<HCompareObjectEqAndBranch>(value, c_constant);
6743 }
6744 builder.Then();
6745 builder.Else();
6746 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6747 Deoptimizer::EAGER);
6748 builder.End();
6749 }
6750 }
6751 HConstant* cell_constant = Add<HConstant>(cell);
6752 auto access = HObjectAccess::ForPropertyCellValue();
6753 if (cell_type == PropertyCellType::kConstantType) {
6754 switch (cell->GetConstantType()) {
6755 case PropertyCellConstantType::kSmi:
6756 access = access.WithRepresentation(Representation::Smi());
6757 break;
6758 case PropertyCellConstantType::kStableMap: {
6759 // The map may no longer be stable, deopt if it's ever different from
6760 // what is currently there, which will allow for restablization.
6761 Handle<Map> map(HeapObject::cast(cell->value())->map());
6762 Add<HCheckHeapObject>(value);
6763 value = Add<HCheckMaps>(value, map);
6764 access = access.WithRepresentation(Representation::HeapObject());
6765 break;
6766 }
6767 }
6768 }
6769 HInstruction* instr = Add<HStoreNamedField>(cell_constant, access, value);
6770 instr->ClearChangesFlag(kInobjectFields);
6771 instr->SetChangesFlag(kGlobalVars);
6772 if (instr->HasObservableSideEffects()) {
6773 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6774 }
6775 }
6685 6776
6686 // Because not every expression has a position and there is not common 6777 // Because not every expression has a position and there is not common
6687 // superclass of Assignment and CountOperation, we cannot just pass the 6778 // superclass of Assignment and CountOperation, we cannot just pass the
6688 // owning expression instead of position and ast_id separately. 6779 // owning expression instead of position and ast_id separately.
6689 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 6780 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
6690 Variable* var, HValue* value, FeedbackVectorSlot slot, BailoutId ast_id) { 6781 Variable* var, HValue* value, FeedbackVectorSlot slot, BailoutId ast_id) {
6691 Handle<JSGlobalObject> global(current_info()->global_object()); 6782 Handle<JSGlobalObject> global(current_info()->global_object());
6692 6783
6693 // Lookup in script contexts. 6784 // Lookup in script contexts.
6694 { 6785 {
(...skipping 20 matching lines...) Expand all
6715 Add<HConstant>(script_context), 6806 Add<HConstant>(script_context),
6716 HObjectAccess::ForContextSlot(lookup.slot_index), value); 6807 HObjectAccess::ForContextSlot(lookup.slot_index), value);
6717 USE(instr); 6808 USE(instr);
6718 DCHECK(instr->HasObservableSideEffects()); 6809 DCHECK(instr->HasObservableSideEffects());
6719 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6810 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6720 return; 6811 return;
6721 } 6812 }
6722 } 6813 }
6723 6814
6724 LookupIterator it(global, var->name(), LookupIterator::OWN); 6815 LookupIterator it(global, var->name(), LookupIterator::OWN);
6725 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 6816 if (CanInlineGlobalPropertyAccess(var, &it, STORE)) {
6726 if (type == kUseCell) { 6817 InlineGlobalPropertyStore(&it, value, ast_id);
6727 Handle<PropertyCell> cell = it.GetPropertyCell();
6728 top_info()->dependencies()->AssumePropertyCell(cell);
6729 auto cell_type = it.property_details().cell_type();
6730 if (cell_type == PropertyCellType::kConstant ||
6731 cell_type == PropertyCellType::kUndefined) {
6732 Handle<Object> constant(cell->value(), isolate());
6733 if (value->IsConstant()) {
6734 HConstant* c_value = HConstant::cast(value);
6735 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6736 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6737 Deoptimizer::EAGER);
6738 }
6739 } else {
6740 HValue* c_constant = Add<HConstant>(constant);
6741 IfBuilder builder(this);
6742 if (constant->IsNumber()) {
6743 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ);
6744 } else {
6745 builder.If<HCompareObjectEqAndBranch>(value, c_constant);
6746 }
6747 builder.Then();
6748 builder.Else();
6749 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6750 Deoptimizer::EAGER);
6751 builder.End();
6752 }
6753 }
6754 HConstant* cell_constant = Add<HConstant>(cell);
6755 auto access = HObjectAccess::ForPropertyCellValue();
6756 if (cell_type == PropertyCellType::kConstantType) {
6757 switch (cell->GetConstantType()) {
6758 case PropertyCellConstantType::kSmi:
6759 access = access.WithRepresentation(Representation::Smi());
6760 break;
6761 case PropertyCellConstantType::kStableMap: {
6762 // The map may no longer be stable, deopt if it's ever different from
6763 // what is currently there, which will allow for restablization.
6764 Handle<Map> map(HeapObject::cast(cell->value())->map());
6765 Add<HCheckHeapObject>(value);
6766 value = Add<HCheckMaps>(value, map);
6767 access = access.WithRepresentation(Representation::HeapObject());
6768 break;
6769 }
6770 }
6771 }
6772 HInstruction* instr = Add<HStoreNamedField>(cell_constant, access, value);
6773 instr->ClearChangesFlag(kInobjectFields);
6774 instr->SetChangesFlag(kGlobalVars);
6775 if (instr->HasObservableSideEffects()) {
6776 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6777 }
6778 } else { 6818 } else {
6779 HValue* global_object = Add<HLoadNamedField>( 6819 HValue* global_object = Add<HLoadNamedField>(
6780 BuildGetNativeContext(), nullptr, 6820 BuildGetNativeContext(), nullptr,
6781 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX)); 6821 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX));
6782 Handle<TypeFeedbackVector> vector = 6822 Handle<TypeFeedbackVector> vector =
6783 handle(current_feedback_vector(), isolate()); 6823 handle(current_feedback_vector(), isolate());
6784 HValue* name = Add<HConstant>(var->name()); 6824 HValue* name = Add<HConstant>(var->name());
6785 HValue* vector_value = Add<HConstant>(vector); 6825 HValue* vector_value = Add<HConstant>(vector);
6786 HValue* slot_value = Add<HConstant>(vector->GetIndex(slot)); 6826 HValue* slot_value = Add<HConstant>(vector->GetIndex(slot));
6787 Callable callable = CodeFactory::StoreICInOptimizedCode( 6827 Callable callable = CodeFactory::StoreICInOptimizedCode(
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
7683 7723
7684 HValue* HOptimizedGraphBuilder::BuildNamedAccess( 7724 HValue* HOptimizedGraphBuilder::BuildNamedAccess(
7685 PropertyAccessType access, BailoutId ast_id, BailoutId return_id, 7725 PropertyAccessType access, BailoutId ast_id, BailoutId return_id,
7686 Expression* expr, FeedbackVectorSlot slot, HValue* object, 7726 Expression* expr, FeedbackVectorSlot slot, HValue* object,
7687 Handle<Name> name, HValue* value, bool is_uninitialized) { 7727 Handle<Name> name, HValue* value, bool is_uninitialized) {
7688 SmallMapList* maps; 7728 SmallMapList* maps;
7689 ComputeReceiverTypes(expr, object, &maps, this); 7729 ComputeReceiverTypes(expr, object, &maps, this);
7690 DCHECK(maps != NULL); 7730 DCHECK(maps != NULL);
7691 7731
7692 if (maps->length() > 0) { 7732 if (maps->length() > 0) {
7733 Handle<JSGlobalObject> global_object(current_info()->global_object());
7734 Handle<Context> current_context(current_info()->context());
7735 Handle<JSObject> global_proxy(current_context->global_proxy());
7736
7737 // Check for special case: Access via a single map to the global proxy
7738 // can also be handled monomorphically.
7739 Handle<Object> map_constructor =
7740 handle(maps->first()->GetConstructor(), isolate());
7741 if (map_constructor->IsJSFunction()) {
7742 Handle<Context> map_context =
7743 handle(Handle<JSFunction>::cast(map_constructor)->context());
7744 bool is_global_proxy_access =
7745 maps->length() == 1 // More than one map, fallback to polymorphic?.
7746 && maps->first()->IsJSGlobalProxyMap() &&
7747 isolate()->MayAccess(map_context, global_proxy);
7748
7749 if (is_global_proxy_access) {
7750 LookupIterator default_it(global_object, name, LookupIterator::OWN);
7751 // TODO(peterssen): Inline LOADS only?.
7752 LookupIterator it = (access == LOAD)
7753 ? TryReadingFromCache(isolate(), &default_it)
7754 : default_it;
7755
7756 if (CanInlineGlobalPropertyAccess(&it, access)) {
7757 BuildCheckHeapObject(object);
7758 Add<HCheckMaps>(object, maps);
7759 if (access == LOAD) {
7760 InlineGlobalPropertyLoad(&it, expr->id());
7761 } else {
7762 InlineGlobalPropertyStore(&it, value, expr->id());
7763 }
7764 return nullptr;
7765 }
7766 }
7767 }
7768
7693 PropertyAccessInfo info(this, access, maps->first(), name); 7769 PropertyAccessInfo info(this, access, maps->first(), name);
7694 if (!info.CanAccessAsMonomorphic(maps)) { 7770 if (!info.CanAccessAsMonomorphic(maps)) {
7695 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, 7771 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id,
7696 object, value, maps, name); 7772 object, value, maps, name);
7697 return NULL; 7773 return NULL;
7698 } 7774 }
7699 7775
7700 HValue* checked_object; 7776 HValue* checked_object;
7701 // AstType::Number() is only supported by polymorphic load/call handling. 7777 // AstType::Number() is only supported by polymorphic load/call handling.
7702 DCHECK(!info.IsNumberType()); 7778 DCHECK(!info.IsNumberType());
(...skipping 5585 matching lines...) Expand 10 before | Expand all | Expand 10 after
13288 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13364 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13289 } 13365 }
13290 13366
13291 #ifdef DEBUG 13367 #ifdef DEBUG
13292 graph_->Verify(false); // No full verify. 13368 graph_->Verify(false); // No full verify.
13293 #endif 13369 #endif
13294 } 13370 }
13295 13371
13296 } // namespace internal 13372 } // namespace internal
13297 } // namespace v8 13373 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698