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 |