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

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

Issue 2403003002: Speedup access to global_proxy.* attributes/accessors. (Closed)
Patch Set: Check for nullptr return in InlineGlobalPropertyStore. Created 4 years, 1 month 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') | no next file » | 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 5181 matching lines...) Expand 10 before | Expand all | Expand 10 after
5192 5192
5193 if (!ast_context()->IsTest()) { 5193 if (!ast_context()->IsTest()) {
5194 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 5194 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
5195 set_current_block(join); 5195 set_current_block(join);
5196 if (join != NULL && !ast_context()->IsEffect()) { 5196 if (join != NULL && !ast_context()->IsEffect()) {
5197 return ast_context()->ReturnValue(Pop()); 5197 return ast_context()->ReturnValue(Pop());
5198 } 5198 }
5199 } 5199 }
5200 } 5200 }
5201 5201
5202 bool HOptimizedGraphBuilder::CanInlineGlobalPropertyAccess(
5203 Variable* var, LookupIterator* it, PropertyAccessType access_type) {
5204 if (var->is_this()) return false;
5205 return CanInlineGlobalPropertyAccess(it, access_type);
5206 }
5202 5207
5203 HOptimizedGraphBuilder::GlobalPropertyAccess 5208 bool HOptimizedGraphBuilder::CanInlineGlobalPropertyAccess(
5204 HOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it, 5209 LookupIterator* it, PropertyAccessType access_type) {
5205 PropertyAccessType access_type) { 5210 if (!current_info()->has_global_object()) {
5206 if (var->is_this() || !current_info()->has_global_object()) { 5211 return false;
5207 return kUseGeneric;
5208 } 5212 }
5209 5213
5210 switch (it->state()) { 5214 switch (it->state()) {
5211 case LookupIterator::ACCESSOR: 5215 case LookupIterator::ACCESSOR:
5212 case LookupIterator::ACCESS_CHECK: 5216 case LookupIterator::ACCESS_CHECK:
5213 case LookupIterator::INTERCEPTOR: 5217 case LookupIterator::INTERCEPTOR:
5214 case LookupIterator::INTEGER_INDEXED_EXOTIC: 5218 case LookupIterator::INTEGER_INDEXED_EXOTIC:
5215 case LookupIterator::NOT_FOUND: 5219 case LookupIterator::NOT_FOUND:
5216 return kUseGeneric; 5220 return false;
5217 case LookupIterator::DATA: 5221 case LookupIterator::DATA:
5218 if (access_type == STORE && it->IsReadOnly()) return kUseGeneric; 5222 if (access_type == STORE && it->IsReadOnly()) return false;
5219 if (!it->GetHolder<JSObject>()->IsJSGlobalObject()) return kUseGeneric; 5223 if (!it->GetHolder<JSObject>()->IsJSGlobalObject()) return false;
5220 return kUseCell; 5224 return true;
5221 case LookupIterator::JSPROXY: 5225 case LookupIterator::JSPROXY:
5222 case LookupIterator::TRANSITION: 5226 case LookupIterator::TRANSITION:
5223 UNREACHABLE(); 5227 UNREACHABLE();
5224 } 5228 }
5225 UNREACHABLE(); 5229 UNREACHABLE();
5226 return kUseGeneric; 5230 return false;
5227 } 5231 }
5228 5232
5229 5233
5230 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 5234 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
5231 DCHECK(var->IsContextSlot()); 5235 DCHECK(var->IsContextSlot());
5232 HValue* context = environment()->context(); 5236 HValue* context = environment()->context();
5233 int length = scope()->ContextChainLength(var->scope()); 5237 int length = scope()->ContextChainLength(var->scope());
5234 while (length-- > 0) { 5238 while (length-- > 0) {
5235 context = Add<HLoadNamedField>( 5239 context = Add<HLoadNamedField>(
5236 context, nullptr, 5240 context, nullptr,
5237 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 5241 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
5238 } 5242 }
5239 return context; 5243 return context;
5240 } 5244 }
5241 5245
5246 void HOptimizedGraphBuilder::InlineGlobalPropertyLoad(LookupIterator* it,
5247 BailoutId ast_id) {
5248 Handle<PropertyCell> cell = it->GetPropertyCell();
5249 top_info()->dependencies()->AssumePropertyCell(cell);
5250 auto cell_type = it->property_details().cell_type();
5251 if (cell_type == PropertyCellType::kConstant ||
5252 cell_type == PropertyCellType::kUndefined) {
5253 Handle<Object> constant_object(cell->value(), isolate());
5254 if (constant_object->IsConsString()) {
5255 constant_object = String::Flatten(Handle<String>::cast(constant_object));
5256 }
5257 HConstant* constant = New<HConstant>(constant_object);
5258 return ast_context()->ReturnInstruction(constant, ast_id);
5259 } else {
5260 auto access = HObjectAccess::ForPropertyCellValue();
5261 UniqueSet<Map>* field_maps = nullptr;
5262 if (cell_type == PropertyCellType::kConstantType) {
5263 switch (cell->GetConstantType()) {
5264 case PropertyCellConstantType::kSmi:
5265 access = access.WithRepresentation(Representation::Smi());
5266 break;
5267 case PropertyCellConstantType::kStableMap: {
5268 // Check that the map really is stable. The heap object could
5269 // have mutated without the cell updating state. In that case,
5270 // make no promises about the loaded value except that it's a
5271 // heap object.
5272 access = access.WithRepresentation(Representation::HeapObject());
5273 Handle<Map> map(HeapObject::cast(cell->value())->map());
5274 if (map->is_stable()) {
5275 field_maps = new (zone())
5276 UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone());
5277 }
5278 break;
5279 }
5280 }
5281 }
5282 HConstant* cell_constant = Add<HConstant>(cell);
5283 HLoadNamedField* instr;
5284 if (field_maps == nullptr) {
5285 instr = New<HLoadNamedField>(cell_constant, nullptr, access);
5286 } else {
5287 instr = New<HLoadNamedField>(cell_constant, nullptr, access, field_maps,
5288 HType::HeapObject());
5289 }
5290 instr->ClearDependsOnFlag(kInobjectFields);
5291 instr->SetDependsOnFlag(kGlobalVars);
5292 return ast_context()->ReturnInstruction(instr, ast_id);
5293 }
5294 }
5242 5295
5243 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 5296 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
5244 DCHECK(!HasStackOverflow()); 5297 DCHECK(!HasStackOverflow());
5245 DCHECK(current_block() != NULL); 5298 DCHECK(current_block() != NULL);
5246 DCHECK(current_block()->HasPredecessor()); 5299 DCHECK(current_block()->HasPredecessor());
5247 Variable* variable = expr->var(); 5300 Variable* variable = expr->var();
5248 switch (variable->location()) { 5301 switch (variable->location()) {
5249 case VariableLocation::UNALLOCATED: { 5302 case VariableLocation::UNALLOCATED: {
5250 if (IsLexicalVariableMode(variable->mode())) { 5303 if (IsLexicalVariableMode(variable->mode())) {
5251 // TODO(rossberg): should this be an DCHECK? 5304 // TODO(rossberg): should this be an DCHECK?
(...skipping 28 matching lines...) Expand all
5280 return Bailout(kReferenceToUninitializedVariable); 5333 return Bailout(kReferenceToUninitializedVariable);
5281 } 5334 }
5282 HInstruction* result = New<HLoadNamedField>( 5335 HInstruction* result = New<HLoadNamedField>(
5283 Add<HConstant>(script_context), nullptr, 5336 Add<HConstant>(script_context), nullptr,
5284 HObjectAccess::ForContextSlot(lookup.slot_index)); 5337 HObjectAccess::ForContextSlot(lookup.slot_index));
5285 return ast_context()->ReturnInstruction(result, expr->id()); 5338 return ast_context()->ReturnInstruction(result, expr->id());
5286 } 5339 }
5287 } 5340 }
5288 5341
5289 LookupIterator it(global, variable->name(), LookupIterator::OWN); 5342 LookupIterator it(global, variable->name(), LookupIterator::OWN);
5290 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); 5343 if (CanInlineGlobalPropertyAccess(variable, &it, LOAD)) {
5291 5344 InlineGlobalPropertyLoad(&it, expr->id());
5292 if (type == kUseCell) { 5345 return;
5293 Handle<PropertyCell> cell = it.GetPropertyCell();
5294 top_info()->dependencies()->AssumePropertyCell(cell);
5295 auto cell_type = it.property_details().cell_type();
5296 if (cell_type == PropertyCellType::kConstant ||
5297 cell_type == PropertyCellType::kUndefined) {
5298 Handle<Object> constant_object(cell->value(), isolate());
5299 if (constant_object->IsConsString()) {
5300 constant_object =
5301 String::Flatten(Handle<String>::cast(constant_object));
5302 }
5303 HConstant* constant = New<HConstant>(constant_object);
5304 return ast_context()->ReturnInstruction(constant, expr->id());
5305 } else {
5306 auto access = HObjectAccess::ForPropertyCellValue();
5307 UniqueSet<Map>* field_maps = nullptr;
5308 if (cell_type == PropertyCellType::kConstantType) {
5309 switch (cell->GetConstantType()) {
5310 case PropertyCellConstantType::kSmi:
5311 access = access.WithRepresentation(Representation::Smi());
5312 break;
5313 case PropertyCellConstantType::kStableMap: {
5314 // Check that the map really is stable. The heap object could
5315 // have mutated without the cell updating state. In that case,
5316 // make no promises about the loaded value except that it's a
5317 // heap object.
5318 access =
5319 access.WithRepresentation(Representation::HeapObject());
5320 Handle<Map> map(HeapObject::cast(cell->value())->map());
5321 if (map->is_stable()) {
5322 field_maps = new (zone())
5323 UniqueSet<Map>(Unique<Map>::CreateImmovable(map), zone());
5324 }
5325 break;
5326 }
5327 }
5328 }
5329 HConstant* cell_constant = Add<HConstant>(cell);
5330 HLoadNamedField* instr;
5331 if (field_maps == nullptr) {
5332 instr = New<HLoadNamedField>(cell_constant, nullptr, access);
5333 } else {
5334 instr = New<HLoadNamedField>(cell_constant, nullptr, access,
5335 field_maps, HType::HeapObject());
5336 }
5337 instr->ClearDependsOnFlag(kInobjectFields);
5338 instr->SetDependsOnFlag(kGlobalVars);
5339 return ast_context()->ReturnInstruction(instr, expr->id());
5340 }
5341 } else { 5346 } else {
5342 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); 5347 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
5343 5348
5344 HValue* vector_value = Add<HConstant>(vector); 5349 HValue* vector_value = Add<HConstant>(vector);
5345 HValue* slot_value = 5350 HValue* slot_value =
5346 Add<HConstant>(vector->GetIndex(expr->VariableFeedbackSlot())); 5351 Add<HConstant>(vector->GetIndex(expr->VariableFeedbackSlot()));
5347 Callable callable = CodeFactory::LoadGlobalICInOptimizedCode( 5352 Callable callable = CodeFactory::LoadGlobalICInOptimizedCode(
5348 isolate(), ast_context()->typeof_mode()); 5353 isolate(), ast_context()->typeof_mode());
5349 HValue* stub = Add<HConstant>(callable.code()); 5354 HValue* stub = Add<HConstant>(callable.code());
5350 HValue* values[] = {slot_value, vector_value}; 5355 HValue* values[] = {slot_value, vector_value};
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after
6434 DCHECK(prop != NULL); 6439 DCHECK(prop != NULL);
6435 CHECK_ALIVE(VisitForValue(prop->obj())); 6440 CHECK_ALIVE(VisitForValue(prop->obj()));
6436 if (!prop->key()->IsPropertyName()) { 6441 if (!prop->key()->IsPropertyName()) {
6437 CHECK_ALIVE(VisitForValue(prop->key())); 6442 CHECK_ALIVE(VisitForValue(prop->key()));
6438 } 6443 }
6439 CHECK_ALIVE(VisitForValue(expr->value())); 6444 CHECK_ALIVE(VisitForValue(expr->value()));
6440 BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), 6445 BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(),
6441 expr->AssignmentId(), expr->IsUninitialized()); 6446 expr->AssignmentId(), expr->IsUninitialized());
6442 } 6447 }
6443 6448
6449 HInstruction* HOptimizedGraphBuilder::InlineGlobalPropertyStore(
6450 LookupIterator* it, HValue* value, BailoutId ast_id) {
6451 Handle<PropertyCell> cell = it->GetPropertyCell();
6452 top_info()->dependencies()->AssumePropertyCell(cell);
6453 auto cell_type = it->property_details().cell_type();
6454 if (cell_type == PropertyCellType::kConstant ||
6455 cell_type == PropertyCellType::kUndefined) {
6456 Handle<Object> constant(cell->value(), isolate());
6457 if (value->IsConstant()) {
6458 HConstant* c_value = HConstant::cast(value);
6459 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6460 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6461 Deoptimizer::EAGER);
6462 }
6463 } else {
6464 HValue* c_constant = Add<HConstant>(constant);
6465 IfBuilder builder(this);
6466 if (constant->IsNumber()) {
6467 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ);
6468 } else {
6469 builder.If<HCompareObjectEqAndBranch>(value, c_constant);
6470 }
6471 builder.Then();
6472 builder.Else();
6473 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6474 Deoptimizer::EAGER);
6475 builder.End();
6476 }
6477 }
6478 HConstant* cell_constant = Add<HConstant>(cell);
6479 auto access = HObjectAccess::ForPropertyCellValue();
6480 if (cell_type == PropertyCellType::kConstantType) {
6481 switch (cell->GetConstantType()) {
6482 case PropertyCellConstantType::kSmi:
6483 access = access.WithRepresentation(Representation::Smi());
6484 break;
6485 case PropertyCellConstantType::kStableMap: {
6486 // First check that the previous value of the {cell} still has the
6487 // map that we are about to check the new {value} for. If not, then
6488 // the stable map assumption was invalidated and we cannot continue
6489 // with the optimized code.
6490 Handle<HeapObject> cell_value(HeapObject::cast(cell->value()));
6491 Handle<Map> cell_value_map(cell_value->map());
6492 if (!cell_value_map->is_stable()) {
6493 Bailout(kUnstableConstantTypeHeapObject);
6494 return nullptr;
6495 }
6496 top_info()->dependencies()->AssumeMapStable(cell_value_map);
6497 // Now check that the new {value} is a HeapObject with the same map
6498 Add<HCheckHeapObject>(value);
6499 value = Add<HCheckMaps>(value, cell_value_map);
6500 access = access.WithRepresentation(Representation::HeapObject());
6501 break;
6502 }
6503 }
6504 }
6505 HInstruction* instr = New<HStoreNamedField>(cell_constant, access, value);
6506 instr->ClearChangesFlag(kInobjectFields);
6507 instr->SetChangesFlag(kGlobalVars);
6508 return instr;
6509 }
6444 6510
6445 // Because not every expression has a position and there is not common 6511 // Because not every expression has a position and there is not common
6446 // superclass of Assignment and CountOperation, we cannot just pass the 6512 // superclass of Assignment and CountOperation, we cannot just pass the
6447 // owning expression instead of position and ast_id separately. 6513 // owning expression instead of position and ast_id separately.
6448 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 6514 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
6449 Variable* var, HValue* value, FeedbackVectorSlot slot, BailoutId ast_id) { 6515 Variable* var, HValue* value, FeedbackVectorSlot slot, BailoutId ast_id) {
6450 Handle<JSGlobalObject> global(current_info()->global_object()); 6516 Handle<JSGlobalObject> global(current_info()->global_object());
6451 6517
6452 // Lookup in script contexts. 6518 // Lookup in script contexts.
6453 { 6519 {
(...skipping 20 matching lines...) Expand all
6474 Add<HConstant>(script_context), 6540 Add<HConstant>(script_context),
6475 HObjectAccess::ForContextSlot(lookup.slot_index), value); 6541 HObjectAccess::ForContextSlot(lookup.slot_index), value);
6476 USE(instr); 6542 USE(instr);
6477 DCHECK(instr->HasObservableSideEffects()); 6543 DCHECK(instr->HasObservableSideEffects());
6478 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6544 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6479 return; 6545 return;
6480 } 6546 }
6481 } 6547 }
6482 6548
6483 LookupIterator it(global, var->name(), LookupIterator::OWN); 6549 LookupIterator it(global, var->name(), LookupIterator::OWN);
6484 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 6550 if (CanInlineGlobalPropertyAccess(var, &it, STORE)) {
6485 if (type == kUseCell) { 6551 HInstruction* instr = InlineGlobalPropertyStore(&it, value, ast_id);
6486 Handle<PropertyCell> cell = it.GetPropertyCell(); 6552 if (!instr) return;
6487 top_info()->dependencies()->AssumePropertyCell(cell); 6553 AddInstruction(instr);
6488 auto cell_type = it.property_details().cell_type();
6489 if (cell_type == PropertyCellType::kConstant ||
6490 cell_type == PropertyCellType::kUndefined) {
6491 Handle<Object> constant(cell->value(), isolate());
6492 if (value->IsConstant()) {
6493 HConstant* c_value = HConstant::cast(value);
6494 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6495 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6496 Deoptimizer::EAGER);
6497 }
6498 } else {
6499 HValue* c_constant = Add<HConstant>(constant);
6500 IfBuilder builder(this);
6501 if (constant->IsNumber()) {
6502 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ);
6503 } else {
6504 builder.If<HCompareObjectEqAndBranch>(value, c_constant);
6505 }
6506 builder.Then();
6507 builder.Else();
6508 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment,
6509 Deoptimizer::EAGER);
6510 builder.End();
6511 }
6512 }
6513 HConstant* cell_constant = Add<HConstant>(cell);
6514 auto access = HObjectAccess::ForPropertyCellValue();
6515 if (cell_type == PropertyCellType::kConstantType) {
6516 switch (cell->GetConstantType()) {
6517 case PropertyCellConstantType::kSmi:
6518 access = access.WithRepresentation(Representation::Smi());
6519 break;
6520 case PropertyCellConstantType::kStableMap: {
6521 // First check that the previous value of the {cell} still has the
6522 // map that we are about to check the new {value} for. If not, then
6523 // the stable map assumption was invalidated and we cannot continue
6524 // with the optimized code.
6525 Handle<HeapObject> cell_value(HeapObject::cast(cell->value()));
6526 Handle<Map> cell_value_map(cell_value->map());
6527 if (!cell_value_map->is_stable()) {
6528 return Bailout(kUnstableConstantTypeHeapObject);
6529 }
6530 top_info()->dependencies()->AssumeMapStable(cell_value_map);
6531 // Now check that the new {value} is a HeapObject with the same map.
6532 Add<HCheckHeapObject>(value);
6533 value = Add<HCheckMaps>(value, cell_value_map);
6534 access = access.WithRepresentation(Representation::HeapObject());
6535 break;
6536 }
6537 }
6538 }
6539 HInstruction* instr = Add<HStoreNamedField>(cell_constant, access, value);
6540 instr->ClearChangesFlag(kInobjectFields);
6541 instr->SetChangesFlag(kGlobalVars);
6542 if (instr->HasObservableSideEffects()) { 6554 if (instr->HasObservableSideEffects()) {
6543 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6555 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6544 } 6556 }
6545 } else { 6557 } else {
6546 HValue* global_object = Add<HLoadNamedField>( 6558 HValue* global_object = Add<HLoadNamedField>(
6547 BuildGetNativeContext(), nullptr, 6559 BuildGetNativeContext(), nullptr,
6548 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX)); 6560 HObjectAccess::ForContextSlot(Context::EXTENSION_INDEX));
6549 Handle<TypeFeedbackVector> vector = 6561 Handle<TypeFeedbackVector> vector =
6550 handle(current_feedback_vector(), isolate()); 6562 handle(current_feedback_vector(), isolate());
6551 HValue* name = Add<HConstant>(var->name()); 6563 HValue* name = Add<HConstant>(var->name());
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
7453 } 7465 }
7454 7466
7455 HValue* HOptimizedGraphBuilder::BuildNamedAccess( 7467 HValue* HOptimizedGraphBuilder::BuildNamedAccess(
7456 PropertyAccessType access, BailoutId ast_id, BailoutId return_id, 7468 PropertyAccessType access, BailoutId ast_id, BailoutId return_id,
7457 Expression* expr, FeedbackVectorSlot slot, HValue* object, 7469 Expression* expr, FeedbackVectorSlot slot, HValue* object,
7458 Handle<Name> name, HValue* value, bool is_uninitialized) { 7470 Handle<Name> name, HValue* value, bool is_uninitialized) {
7459 SmallMapList* maps; 7471 SmallMapList* maps;
7460 ComputeReceiverTypes(expr, object, &maps, this); 7472 ComputeReceiverTypes(expr, object, &maps, this);
7461 DCHECK(maps != NULL); 7473 DCHECK(maps != NULL);
7462 7474
7475 // Check for special case: Access via a single map to the global proxy
7476 // can also be handled monomorphically.
7463 if (maps->length() > 0) { 7477 if (maps->length() > 0) {
7478 Handle<Object> map_constructor =
7479 handle(maps->first()->GetConstructor(), isolate());
7480 if (map_constructor->IsJSFunction()) {
7481 Handle<Context> map_context =
7482 handle(Handle<JSFunction>::cast(map_constructor)->context());
7483 Handle<Context> current_context(current_info()->context());
7484 bool is_same_context_global_proxy_access =
7485 maps->length() == 1 && // >1 map => fallback to polymorphic
7486 maps->first()->IsJSGlobalProxyMap() &&
7487 (*map_context == *current_context);
7488 if (is_same_context_global_proxy_access) {
7489 Handle<JSGlobalObject> global_object(current_info()->global_object());
7490 LookupIterator it(global_object, name, LookupIterator::OWN);
7491 if (CanInlineGlobalPropertyAccess(&it, access)) {
7492 BuildCheckHeapObject(object);
7493 Add<HCheckMaps>(object, maps);
7494 if (access == LOAD) {
7495 InlineGlobalPropertyLoad(&it, expr->id());
7496 return nullptr;
7497 } else {
7498 return InlineGlobalPropertyStore(&it, value, expr->id());
7499 }
7500 }
7501 }
7502 }
7503
7464 PropertyAccessInfo info(this, access, maps->first(), name); 7504 PropertyAccessInfo info(this, access, maps->first(), name);
7465 if (!info.CanAccessAsMonomorphic(maps)) { 7505 if (!info.CanAccessAsMonomorphic(maps)) {
7466 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, 7506 HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id,
7467 object, value, maps, name); 7507 object, value, maps, name);
7468 return NULL; 7508 return NULL;
7469 } 7509 }
7470 7510
7471 HValue* checked_object; 7511 HValue* checked_object;
7472 // AstType::Number() is only supported by polymorphic load/call handling. 7512 // AstType::Number() is only supported by polymorphic load/call handling.
7473 DCHECK(!info.IsNumberType()); 7513 DCHECK(!info.IsNumberType());
(...skipping 5521 matching lines...) Expand 10 before | Expand all | Expand 10 after
12995 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13035 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12996 } 13036 }
12997 13037
12998 #ifdef DEBUG 13038 #ifdef DEBUG
12999 graph_->Verify(false); // No full verify. 13039 graph_->Verify(false); // No full verify.
13000 #endif 13040 #endif
13001 } 13041 }
13002 13042
13003 } // namespace internal 13043 } // namespace internal
13004 } // namespace v8 13044 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698