OLD | NEW |
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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 5268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5279 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); | 5279 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); |
5280 set_current_block(join); | 5280 set_current_block(join); |
5281 if (join != NULL && !ast_context()->IsEffect()) { | 5281 if (join != NULL && !ast_context()->IsEffect()) { |
5282 return ast_context()->ReturnValue(Pop()); | 5282 return ast_context()->ReturnValue(Pop()); |
5283 } | 5283 } |
5284 } | 5284 } |
5285 } | 5285 } |
5286 | 5286 |
5287 | 5287 |
5288 HOptimizedGraphBuilder::GlobalPropertyAccess | 5288 HOptimizedGraphBuilder::GlobalPropertyAccess |
5289 HOptimizedGraphBuilder::LookupGlobalProperty( | 5289 HOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it, |
5290 Variable* var, LookupResult* lookup, PropertyAccessType access_type) { | 5290 PropertyAccessType access_type) { |
| 5291 DCHECK_EQ(*var->name(), *it->name()); |
5291 if (var->is_this() || !current_info()->has_global_object()) { | 5292 if (var->is_this() || !current_info()->has_global_object()) { |
5292 return kUseGeneric; | 5293 return kUseGeneric; |
5293 } | 5294 } |
5294 Handle<GlobalObject> global(current_info()->global_object()); | 5295 if (!it->HasProperty() || it->property_kind() != LookupIterator::DATA || |
5295 global->Lookup(var->name(), lookup); | 5296 (access_type == STORE && it->IsReadOnly())) { |
5296 if (!lookup->IsNormal() || | |
5297 (access_type == STORE && lookup->IsReadOnly()) || | |
5298 lookup->holder() != *global) { | |
5299 return kUseGeneric; | 5297 return kUseGeneric; |
5300 } | 5298 } |
5301 | 5299 |
5302 return kUseCell; | 5300 return kUseCell; |
5303 } | 5301 } |
5304 | 5302 |
5305 | 5303 |
5306 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5304 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
5307 DCHECK(var->IsContextSlot()); | 5305 DCHECK(var->IsContextSlot()); |
5308 HValue* context = environment()->context(); | 5306 HValue* context = environment()->context(); |
(...skipping 24 matching lines...) Expand all Loading... |
5333 } | 5331 } |
5334 // Handle known global constants like 'undefined' specially to avoid a | 5332 // Handle known global constants like 'undefined' specially to avoid a |
5335 // load from a global cell for them. | 5333 // load from a global cell for them. |
5336 Handle<Object> constant_value = | 5334 Handle<Object> constant_value = |
5337 isolate()->factory()->GlobalConstantFor(variable->name()); | 5335 isolate()->factory()->GlobalConstantFor(variable->name()); |
5338 if (!constant_value.is_null()) { | 5336 if (!constant_value.is_null()) { |
5339 HConstant* instr = New<HConstant>(constant_value); | 5337 HConstant* instr = New<HConstant>(constant_value); |
5340 return ast_context()->ReturnInstruction(instr, expr->id()); | 5338 return ast_context()->ReturnInstruction(instr, expr->id()); |
5341 } | 5339 } |
5342 | 5340 |
5343 LookupResult lookup(isolate()); | 5341 Handle<GlobalObject> global(current_info()->global_object()); |
5344 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, LOAD); | 5342 LookupIterator it(global, variable->name(), |
| 5343 LookupIterator::CHECK_PROPERTY); |
| 5344 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); |
5345 | 5345 |
5346 if (type == kUseCell && | 5346 if (type == kUseCell && |
5347 current_info()->global_object()->IsAccessCheckNeeded()) { | 5347 current_info()->global_object()->IsAccessCheckNeeded()) { |
5348 type = kUseGeneric; | 5348 type = kUseGeneric; |
5349 } | 5349 } |
5350 | 5350 |
5351 if (type == kUseCell) { | 5351 if (type == kUseCell) { |
5352 Handle<GlobalObject> global(current_info()->global_object()); | 5352 Handle<PropertyCell> cell = it.GetPropertyCell(); |
5353 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | |
5354 if (cell->type()->IsConstant()) { | 5353 if (cell->type()->IsConstant()) { |
5355 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | 5354 PropertyCell::AddDependentCompilationInfo(cell, top_info()); |
5356 Handle<Object> constant_object = cell->type()->AsConstant()->Value(); | 5355 Handle<Object> constant_object = cell->type()->AsConstant()->Value(); |
5357 if (constant_object->IsConsString()) { | 5356 if (constant_object->IsConsString()) { |
5358 constant_object = | 5357 constant_object = |
5359 String::Flatten(Handle<String>::cast(constant_object)); | 5358 String::Flatten(Handle<String>::cast(constant_object)); |
5360 } | 5359 } |
5361 HConstant* constant = New<HConstant>(constant_object); | 5360 HConstant* constant = New<HConstant>(constant_object); |
5362 return ast_context()->ReturnInstruction(constant, expr->id()); | 5361 return ast_context()->ReturnInstruction(constant, expr->id()); |
5363 } else { | 5362 } else { |
5364 HLoadGlobalCell* instr = | 5363 HLoadGlobalCell* instr = |
5365 New<HLoadGlobalCell>(cell, lookup.GetPropertyDetails()); | 5364 New<HLoadGlobalCell>(cell, it.property_details()); |
5366 return ast_context()->ReturnInstruction(instr, expr->id()); | 5365 return ast_context()->ReturnInstruction(instr, expr->id()); |
5367 } | 5366 } |
5368 } else { | 5367 } else { |
5369 HValue* global_object = Add<HLoadNamedField>( | 5368 HValue* global_object = Add<HLoadNamedField>( |
5370 context(), static_cast<HValue*>(NULL), | 5369 context(), static_cast<HValue*>(NULL), |
5371 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 5370 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
5372 HLoadGlobalGeneric* instr = | 5371 HLoadGlobalGeneric* instr = |
5373 New<HLoadGlobalGeneric>(global_object, | 5372 New<HLoadGlobalGeneric>(global_object, |
5374 variable->name(), | 5373 variable->name(), |
5375 ast_context()->is_for_typeof()); | 5374 ast_context()->is_for_typeof()); |
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6449 } | 6448 } |
6450 | 6449 |
6451 | 6450 |
6452 // Because not every expression has a position and there is not common | 6451 // Because not every expression has a position and there is not common |
6453 // superclass of Assignment and CountOperation, we cannot just pass the | 6452 // superclass of Assignment and CountOperation, we cannot just pass the |
6454 // owning expression instead of position and ast_id separately. | 6453 // owning expression instead of position and ast_id separately. |
6455 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6454 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
6456 Variable* var, | 6455 Variable* var, |
6457 HValue* value, | 6456 HValue* value, |
6458 BailoutId ast_id) { | 6457 BailoutId ast_id) { |
6459 LookupResult lookup(isolate()); | 6458 Handle<GlobalObject> global(current_info()->global_object()); |
6460 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, STORE); | 6459 LookupIterator it(global, var->name(), LookupIterator::CHECK_PROPERTY); |
| 6460 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); |
6461 if (type == kUseCell) { | 6461 if (type == kUseCell) { |
6462 Handle<GlobalObject> global(current_info()->global_object()); | 6462 Handle<PropertyCell> cell = it.GetPropertyCell(); |
6463 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | |
6464 if (cell->type()->IsConstant()) { | 6463 if (cell->type()->IsConstant()) { |
6465 Handle<Object> constant = cell->type()->AsConstant()->Value(); | 6464 Handle<Object> constant = cell->type()->AsConstant()->Value(); |
6466 if (value->IsConstant()) { | 6465 if (value->IsConstant()) { |
6467 HConstant* c_value = HConstant::cast(value); | 6466 HConstant* c_value = HConstant::cast(value); |
6468 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6467 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
6469 Add<HDeoptimize>("Constant global variable assignment", | 6468 Add<HDeoptimize>("Constant global variable assignment", |
6470 Deoptimizer::EAGER); | 6469 Deoptimizer::EAGER); |
6471 } | 6470 } |
6472 } else { | 6471 } else { |
6473 HValue* c_constant = Add<HConstant>(constant); | 6472 HValue* c_constant = Add<HConstant>(constant); |
6474 IfBuilder builder(this); | 6473 IfBuilder builder(this); |
6475 if (constant->IsNumber()) { | 6474 if (constant->IsNumber()) { |
6476 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); | 6475 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); |
6477 } else { | 6476 } else { |
6478 builder.If<HCompareObjectEqAndBranch>(value, c_constant); | 6477 builder.If<HCompareObjectEqAndBranch>(value, c_constant); |
6479 } | 6478 } |
6480 builder.Then(); | 6479 builder.Then(); |
6481 builder.Else(); | 6480 builder.Else(); |
6482 Add<HDeoptimize>("Constant global variable assignment", | 6481 Add<HDeoptimize>("Constant global variable assignment", |
6483 Deoptimizer::EAGER); | 6482 Deoptimizer::EAGER); |
6484 builder.End(); | 6483 builder.End(); |
6485 } | 6484 } |
6486 } | 6485 } |
6487 HInstruction* instr = | 6486 HInstruction* instr = |
6488 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); | 6487 Add<HStoreGlobalCell>(value, cell, it.property_details()); |
6489 if (instr->HasObservableSideEffects()) { | 6488 if (instr->HasObservableSideEffects()) { |
6490 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6489 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
6491 } | 6490 } |
6492 } else { | 6491 } else { |
6493 HValue* global_object = Add<HLoadNamedField>( | 6492 HValue* global_object = Add<HLoadNamedField>( |
6494 context(), static_cast<HValue*>(NULL), | 6493 context(), static_cast<HValue*>(NULL), |
6495 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6494 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
6496 HStoreNamedGeneric* instr = | 6495 HStoreNamedGeneric* instr = |
6497 Add<HStoreNamedGeneric>(global_object, var->name(), | 6496 Add<HStoreNamedGeneric>(global_object, var->name(), |
6498 value, function_strict_mode()); | 6497 value, function_strict_mode()); |
(...skipping 2543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9042 // The function is on the stack in the unoptimized code during | 9041 // The function is on the stack in the unoptimized code during |
9043 // evaluation of the arguments. | 9042 // evaluation of the arguments. |
9044 CHECK_ALIVE(VisitForValue(expr->expression())); | 9043 CHECK_ALIVE(VisitForValue(expr->expression())); |
9045 HValue* function = Top(); | 9044 HValue* function = Top(); |
9046 if (expr->global_call()) { | 9045 if (expr->global_call()) { |
9047 Variable* var = proxy->var(); | 9046 Variable* var = proxy->var(); |
9048 bool known_global_function = false; | 9047 bool known_global_function = false; |
9049 // If there is a global property cell for the name at compile time and | 9048 // If there is a global property cell for the name at compile time and |
9050 // access check is not enabled we assume that the function will not change | 9049 // access check is not enabled we assume that the function will not change |
9051 // and generate optimized code for calling the function. | 9050 // and generate optimized code for calling the function. |
9052 LookupResult lookup(isolate()); | 9051 Handle<GlobalObject> global(current_info()->global_object()); |
9053 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD); | 9052 LookupIterator it(global, var->name(), LookupIterator::CHECK_PROPERTY); |
| 9053 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD); |
9054 if (type == kUseCell && | 9054 if (type == kUseCell && |
9055 !current_info()->global_object()->IsAccessCheckNeeded()) { | 9055 !current_info()->global_object()->IsAccessCheckNeeded()) { |
9056 Handle<GlobalObject> global(current_info()->global_object()); | 9056 Handle<GlobalObject> global(current_info()->global_object()); |
9057 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 9057 known_global_function = expr->ComputeGlobalTarget(global, &it); |
9058 } | 9058 } |
9059 if (known_global_function) { | 9059 if (known_global_function) { |
9060 Add<HCheckValue>(function, expr->target()); | 9060 Add<HCheckValue>(function, expr->target()); |
9061 | 9061 |
9062 // Placeholder for the receiver. | 9062 // Placeholder for the receiver. |
9063 Push(graph()->GetConstantUndefined()); | 9063 Push(graph()->GetConstantUndefined()); |
9064 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9064 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
9065 | 9065 |
9066 // Patch the global object on the stack by the expected receiver. | 9066 // Patch the global object on the stack by the expected receiver. |
9067 HValue* receiver = ImplicitReceiverFor(function, expr->target()); | 9067 HValue* receiver = ImplicitReceiverFor(function, expr->target()); |
(...skipping 3418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12486 if (ShouldProduceTraceOutput()) { | 12486 if (ShouldProduceTraceOutput()) { |
12487 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12487 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12488 } | 12488 } |
12489 | 12489 |
12490 #ifdef DEBUG | 12490 #ifdef DEBUG |
12491 graph_->Verify(false); // No full verify. | 12491 graph_->Verify(false); // No full verify. |
12492 #endif | 12492 #endif |
12493 } | 12493 } |
12494 | 12494 |
12495 } } // namespace v8::internal | 12495 } } // namespace v8::internal |
OLD | NEW |