| 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 5274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5285 if (join != NULL && !ast_context()->IsEffect()) { | 5285 if (join != NULL && !ast_context()->IsEffect()) { |
| 5286 return ast_context()->ReturnValue(Pop()); | 5286 return ast_context()->ReturnValue(Pop()); |
| 5287 } | 5287 } |
| 5288 } | 5288 } |
| 5289 } | 5289 } |
| 5290 | 5290 |
| 5291 | 5291 |
| 5292 HOptimizedGraphBuilder::GlobalPropertyAccess | 5292 HOptimizedGraphBuilder::GlobalPropertyAccess |
| 5293 HOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it, | 5293 HOptimizedGraphBuilder::LookupGlobalProperty(Variable* var, LookupIterator* it, |
| 5294 PropertyAccessType access_type) { | 5294 PropertyAccessType access_type) { |
| 5295 DCHECK_EQ(*var->name(), *it->name()); | |
| 5296 if (var->is_this() || !current_info()->has_global_object()) { | 5295 if (var->is_this() || !current_info()->has_global_object()) { |
| 5297 return kUseGeneric; | 5296 return kUseGeneric; |
| 5298 } | 5297 } |
| 5299 if (!it->HasProperty() || it->property_kind() != LookupIterator::DATA || | 5298 |
| 5300 (access_type == STORE && it->IsReadOnly())) { | 5299 switch (it->state()) { |
| 5301 return kUseGeneric; | 5300 case LookupIterator::ACCESS_CHECK: |
| 5301 case LookupIterator::INTERCEPTOR: |
| 5302 case LookupIterator::NOT_FOUND: |
| 5303 return kUseGeneric; |
| 5304 case LookupIterator::PROPERTY: |
| 5305 if (!it->HasProperty()) return kUseGeneric; |
| 5306 switch (it->property_kind()) { |
| 5307 case LookupIterator::DATA: |
| 5308 if (access_type == STORE && it->IsReadOnly()) return kUseGeneric; |
| 5309 return kUseCell; |
| 5310 case LookupIterator::ACCESSOR: |
| 5311 return kUseGeneric; |
| 5312 } |
| 5313 case LookupIterator::JSPROXY: |
| 5314 case LookupIterator::TRANSITION: |
| 5315 UNREACHABLE(); |
| 5302 } | 5316 } |
| 5303 | 5317 UNREACHABLE(); |
| 5304 return kUseCell; | 5318 return kUseGeneric; |
| 5305 } | 5319 } |
| 5306 | 5320 |
| 5307 | 5321 |
| 5308 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5322 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
| 5309 DCHECK(var->IsContextSlot()); | 5323 DCHECK(var->IsContextSlot()); |
| 5310 HValue* context = environment()->context(); | 5324 HValue* context = environment()->context(); |
| 5311 int length = scope()->ContextChainLength(var->scope()); | 5325 int length = scope()->ContextChainLength(var->scope()); |
| 5312 while (length-- > 0) { | 5326 while (length-- > 0) { |
| 5313 context = Add<HLoadNamedField>( | 5327 context = Add<HLoadNamedField>( |
| 5314 context, static_cast<HValue*>(NULL), | 5328 context, static_cast<HValue*>(NULL), |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5336 // Handle known global constants like 'undefined' specially to avoid a | 5350 // Handle known global constants like 'undefined' specially to avoid a |
| 5337 // load from a global cell for them. | 5351 // load from a global cell for them. |
| 5338 Handle<Object> constant_value = | 5352 Handle<Object> constant_value = |
| 5339 isolate()->factory()->GlobalConstantFor(variable->name()); | 5353 isolate()->factory()->GlobalConstantFor(variable->name()); |
| 5340 if (!constant_value.is_null()) { | 5354 if (!constant_value.is_null()) { |
| 5341 HConstant* instr = New<HConstant>(constant_value); | 5355 HConstant* instr = New<HConstant>(constant_value); |
| 5342 return ast_context()->ReturnInstruction(instr, expr->id()); | 5356 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5343 } | 5357 } |
| 5344 | 5358 |
| 5345 Handle<GlobalObject> global(current_info()->global_object()); | 5359 Handle<GlobalObject> global(current_info()->global_object()); |
| 5346 LookupIterator it(global, variable->name(), LookupIterator::OWN_PROPERTY); | 5360 LookupIterator it(global, variable->name(), |
| 5361 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 5347 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); | 5362 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); |
| 5348 | 5363 |
| 5349 if (type == kUseCell && | |
| 5350 current_info()->global_object()->IsAccessCheckNeeded()) { | |
| 5351 type = kUseGeneric; | |
| 5352 } | |
| 5353 | |
| 5354 if (type == kUseCell) { | 5364 if (type == kUseCell) { |
| 5355 Handle<PropertyCell> cell = it.GetPropertyCell(); | 5365 Handle<PropertyCell> cell = it.GetPropertyCell(); |
| 5356 if (cell->type()->IsConstant()) { | 5366 if (cell->type()->IsConstant()) { |
| 5357 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | 5367 PropertyCell::AddDependentCompilationInfo(cell, top_info()); |
| 5358 Handle<Object> constant_object = cell->type()->AsConstant()->Value(); | 5368 Handle<Object> constant_object = cell->type()->AsConstant()->Value(); |
| 5359 if (constant_object->IsConsString()) { | 5369 if (constant_object->IsConsString()) { |
| 5360 constant_object = | 5370 constant_object = |
| 5361 String::Flatten(Handle<String>::cast(constant_object)); | 5371 String::Flatten(Handle<String>::cast(constant_object)); |
| 5362 } | 5372 } |
| 5363 HConstant* constant = New<HConstant>(constant_object); | 5373 HConstant* constant = New<HConstant>(constant_object); |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5790 | 5800 |
| 5791 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( | 5801 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( |
| 5792 PropertyAccessInfo* info, | 5802 PropertyAccessInfo* info, |
| 5793 HValue* checked_object) { | 5803 HValue* checked_object) { |
| 5794 // See if this is a load for an immutable property | 5804 // See if this is a load for an immutable property |
| 5795 if (checked_object->ActualValue()->IsConstant()) { | 5805 if (checked_object->ActualValue()->IsConstant()) { |
| 5796 Handle<Object> object( | 5806 Handle<Object> object( |
| 5797 HConstant::cast(checked_object->ActualValue())->handle(isolate())); | 5807 HConstant::cast(checked_object->ActualValue())->handle(isolate())); |
| 5798 | 5808 |
| 5799 if (object->IsJSObject()) { | 5809 if (object->IsJSObject()) { |
| 5800 LookupIterator it(object, info->name(), LookupIterator::OWN_PROPERTY); | 5810 LookupIterator it(object, info->name(), |
| 5811 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 5801 Handle<Object> value = JSObject::GetDataProperty(&it); | 5812 Handle<Object> value = JSObject::GetDataProperty(&it); |
| 5802 if (it.IsFound() && it.IsReadOnly() && !it.IsConfigurable()) { | 5813 if (it.IsFound() && it.IsReadOnly() && !it.IsConfigurable()) { |
| 5803 return New<HConstant>(value); | 5814 return New<HConstant>(value); |
| 5804 } | 5815 } |
| 5805 } | 5816 } |
| 5806 } | 5817 } |
| 5807 | 5818 |
| 5808 HObjectAccess access = info->access(); | 5819 HObjectAccess access = info->access(); |
| 5809 if (access.representation().IsDouble()) { | 5820 if (access.representation().IsDouble()) { |
| 5810 // Load the heap number. | 5821 // Load the heap number. |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6454 | 6465 |
| 6455 | 6466 |
| 6456 // Because not every expression has a position and there is not common | 6467 // Because not every expression has a position and there is not common |
| 6457 // superclass of Assignment and CountOperation, we cannot just pass the | 6468 // superclass of Assignment and CountOperation, we cannot just pass the |
| 6458 // owning expression instead of position and ast_id separately. | 6469 // owning expression instead of position and ast_id separately. |
| 6459 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( | 6470 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| 6460 Variable* var, | 6471 Variable* var, |
| 6461 HValue* value, | 6472 HValue* value, |
| 6462 BailoutId ast_id) { | 6473 BailoutId ast_id) { |
| 6463 Handle<GlobalObject> global(current_info()->global_object()); | 6474 Handle<GlobalObject> global(current_info()->global_object()); |
| 6464 LookupIterator it(global, var->name(), LookupIterator::OWN_PROPERTY); | 6475 LookupIterator it(global, var->name(), LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 6465 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); | 6476 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); |
| 6466 if (type == kUseCell) { | 6477 if (type == kUseCell) { |
| 6467 Handle<PropertyCell> cell = it.GetPropertyCell(); | 6478 Handle<PropertyCell> cell = it.GetPropertyCell(); |
| 6468 if (cell->type()->IsConstant()) { | 6479 if (cell->type()->IsConstant()) { |
| 6469 Handle<Object> constant = cell->type()->AsConstant()->Value(); | 6480 Handle<Object> constant = cell->type()->AsConstant()->Value(); |
| 6470 if (value->IsConstant()) { | 6481 if (value->IsConstant()) { |
| 6471 HConstant* c_value = HConstant::cast(value); | 6482 HConstant* c_value = HConstant::cast(value); |
| 6472 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6483 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
| 6473 Add<HDeoptimize>("Constant global variable assignment", | 6484 Add<HDeoptimize>("Constant global variable assignment", |
| 6474 Deoptimizer::EAGER); | 6485 Deoptimizer::EAGER); |
| (...skipping 2565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9040 // evaluation of the arguments. | 9051 // evaluation of the arguments. |
| 9041 CHECK_ALIVE(VisitForValue(expr->expression())); | 9052 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 9042 HValue* function = Top(); | 9053 HValue* function = Top(); |
| 9043 if (expr->global_call()) { | 9054 if (expr->global_call()) { |
| 9044 Variable* var = proxy->var(); | 9055 Variable* var = proxy->var(); |
| 9045 bool known_global_function = false; | 9056 bool known_global_function = false; |
| 9046 // If there is a global property cell for the name at compile time and | 9057 // If there is a global property cell for the name at compile time and |
| 9047 // access check is not enabled we assume that the function will not change | 9058 // access check is not enabled we assume that the function will not change |
| 9048 // and generate optimized code for calling the function. | 9059 // and generate optimized code for calling the function. |
| 9049 Handle<GlobalObject> global(current_info()->global_object()); | 9060 Handle<GlobalObject> global(current_info()->global_object()); |
| 9050 LookupIterator it(global, var->name(), LookupIterator::OWN_PROPERTY); | 9061 LookupIterator it(global, var->name(), |
| 9062 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 9051 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD); | 9063 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD); |
| 9052 if (type == kUseCell && | 9064 if (type == kUseCell) { |
| 9053 !current_info()->global_object()->IsAccessCheckNeeded()) { | |
| 9054 Handle<GlobalObject> global(current_info()->global_object()); | 9065 Handle<GlobalObject> global(current_info()->global_object()); |
| 9055 known_global_function = expr->ComputeGlobalTarget(global, &it); | 9066 known_global_function = expr->ComputeGlobalTarget(global, &it); |
| 9056 } | 9067 } |
| 9057 if (known_global_function) { | 9068 if (known_global_function) { |
| 9058 Add<HCheckValue>(function, expr->target()); | 9069 Add<HCheckValue>(function, expr->target()); |
| 9059 | 9070 |
| 9060 // Placeholder for the receiver. | 9071 // Placeholder for the receiver. |
| 9061 Push(graph()->GetConstantUndefined()); | 9072 Push(graph()->GetConstantUndefined()); |
| 9062 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 9073 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 9063 | 9074 |
| (...skipping 1615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10679 return ast_context()->ReturnControl(result, expr->id()); | 10690 return ast_context()->ReturnControl(result, expr->id()); |
| 10680 } | 10691 } |
| 10681 | 10692 |
| 10682 if (op == Token::INSTANCEOF) { | 10693 if (op == Token::INSTANCEOF) { |
| 10683 // Check to see if the rhs of the instanceof is a global function not | 10694 // Check to see if the rhs of the instanceof is a global function not |
| 10684 // residing in new space. If it is we assume that the function will stay the | 10695 // residing in new space. If it is we assume that the function will stay the |
| 10685 // same. | 10696 // same. |
| 10686 Handle<JSFunction> target = Handle<JSFunction>::null(); | 10697 Handle<JSFunction> target = Handle<JSFunction>::null(); |
| 10687 VariableProxy* proxy = expr->right()->AsVariableProxy(); | 10698 VariableProxy* proxy = expr->right()->AsVariableProxy(); |
| 10688 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); | 10699 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); |
| 10689 if (global_function && | 10700 if (global_function && current_info()->has_global_object()) { |
| 10690 current_info()->has_global_object() && | |
| 10691 !current_info()->global_object()->IsAccessCheckNeeded()) { | |
| 10692 Handle<String> name = proxy->name(); | 10701 Handle<String> name = proxy->name(); |
| 10693 Handle<GlobalObject> global(current_info()->global_object()); | 10702 Handle<GlobalObject> global(current_info()->global_object()); |
| 10694 LookupIterator it(global, name, LookupIterator::OWN_PROPERTY); | 10703 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 10695 Handle<Object> value = JSObject::GetDataProperty(&it); | 10704 Handle<Object> value = JSObject::GetDataProperty(&it); |
| 10696 if (it.IsFound() && value->IsJSFunction()) { | 10705 if (it.IsFound() && value->IsJSFunction()) { |
| 10697 Handle<JSFunction> candidate = Handle<JSFunction>::cast(value); | 10706 Handle<JSFunction> candidate = Handle<JSFunction>::cast(value); |
| 10698 // If the function is in new space we assume it's more likely to | 10707 // If the function is in new space we assume it's more likely to |
| 10699 // change and thus prefer the general IC code. | 10708 // change and thus prefer the general IC code. |
| 10700 if (!isolate()->heap()->InNewSpace(*candidate)) { | 10709 if (!isolate()->heap()->InNewSpace(*candidate)) { |
| 10701 target = candidate; | 10710 target = candidate; |
| 10702 } | 10711 } |
| 10703 } | 10712 } |
| 10704 } | 10713 } |
| (...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12484 if (ShouldProduceTraceOutput()) { | 12493 if (ShouldProduceTraceOutput()) { |
| 12485 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12494 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12486 } | 12495 } |
| 12487 | 12496 |
| 12488 #ifdef DEBUG | 12497 #ifdef DEBUG |
| 12489 graph_->Verify(false); // No full verify. | 12498 graph_->Verify(false); // No full verify. |
| 12490 #endif | 12499 #endif |
| 12491 } | 12500 } |
| 12492 | 12501 |
| 12493 } } // namespace v8::internal | 12502 } } // namespace v8::internal |
| OLD | NEW |