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

Side by Side Diff: src/hydrogen.cc

Issue 1095433002: Refactor compilation dependency handling. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
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/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 5363 matching lines...) Expand 10 before | Expand all | Expand 10 after
5374 HObjectAccess::ForContextSlot(lookup.slot_index)); 5374 HObjectAccess::ForContextSlot(lookup.slot_index));
5375 return ast_context()->ReturnInstruction(result, expr->id()); 5375 return ast_context()->ReturnInstruction(result, expr->id());
5376 } 5376 }
5377 } 5377 }
5378 5378
5379 LookupIterator it(global, variable->name(), LookupIterator::OWN); 5379 LookupIterator it(global, variable->name(), LookupIterator::OWN);
5380 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); 5380 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD);
5381 5381
5382 if (type == kUseCell) { 5382 if (type == kUseCell) {
5383 Handle<PropertyCell> cell = it.GetPropertyCell(); 5383 Handle<PropertyCell> cell = it.GetPropertyCell();
5384 PropertyCell::AddDependentCompilationInfo(cell, top_info()); 5384 top_info()->dependencies()->AssumePropertyCell(cell);
5385 if (it.property_details().cell_type() == PropertyCellType::kConstant) { 5385 if (it.property_details().cell_type() == PropertyCellType::kConstant) {
5386 Handle<Object> constant_object(cell->value(), isolate()); 5386 Handle<Object> constant_object(cell->value(), isolate());
5387 if (constant_object->IsConsString()) { 5387 if (constant_object->IsConsString()) {
5388 constant_object = 5388 constant_object =
5389 String::Flatten(Handle<String>::cast(constant_object)); 5389 String::Flatten(Handle<String>::cast(constant_object));
5390 } 5390 }
5391 HConstant* constant = New<HConstant>(constant_object); 5391 HConstant* constant = New<HConstant>(constant_object);
5392 return ast_context()->ReturnInstruction(constant, expr->id()); 5392 return ast_context()->ReturnInstruction(constant, expr->id());
5393 } else { 5393 } else {
5394 HConstant* cell_constant = Add<HConstant>(cell); 5394 HConstant* cell_constant = Add<HConstant>(cell);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
5755 Add<HConstant>(literal_index), 5755 Add<HConstant>(literal_index),
5756 Add<HConstant>(constants), 5756 Add<HConstant>(constants),
5757 Add<HConstant>(flags)); 5757 Add<HConstant>(flags));
5758 5758
5759 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5759 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
5760 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5760 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5761 Runtime::FunctionForId(function_id), 5761 Runtime::FunctionForId(function_id),
5762 4); 5762 4);
5763 5763
5764 // Register to deopt if the boilerplate ElementsKind changes. 5764 // Register to deopt if the boilerplate ElementsKind changes.
5765 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 5765 top_info()->dependencies()->AssumeTransitionStable(site);
5766 } 5766 }
5767 5767
5768 // The array is expected in the bailout environment during computation 5768 // The array is expected in the bailout environment during computation
5769 // of the property values and is the value of the entire expression. 5769 // of the property values and is the value of the entire expression.
5770 Push(literal); 5770 Push(literal);
5771 // The literal index is on the stack, too. 5771 // The literal index is on the stack, too.
5772 Push(Add<HConstant>(expr->literal_index())); 5772 Push(Add<HConstant>(expr->literal_index()));
5773 5773
5774 HInstruction* elements = NULL; 5774 HInstruction* elements = NULL;
5775 5775
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
6070 } 6070 }
6071 6071
6072 field_maps_.Sort(); 6072 field_maps_.Sort();
6073 DCHECK_EQ(num_field_maps, field_maps_.length()); 6073 DCHECK_EQ(num_field_maps, field_maps_.length());
6074 6074
6075 // Determine field HType from field HeapType. 6075 // Determine field HType from field HeapType.
6076 field_type_ = HType::FromType<HeapType>(field_type); 6076 field_type_ = HType::FromType<HeapType>(field_type);
6077 DCHECK(field_type_.IsHeapObject()); 6077 DCHECK(field_type_.IsHeapObject());
6078 6078
6079 // Add dependency on the map that introduced the field. 6079 // Add dependency on the map that introduced the field.
6080 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), 6080 top_info()->dependencies()->AssumeFieldType(GetFieldOwnerFromMap(map));
6081 DependentCode::kFieldTypeGroup, top_info());
6082 return true; 6081 return true;
6083 } 6082 }
6084 6083
6085 6084
6086 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 6085 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
6087 Handle<Map> map = this->map(); 6086 Handle<Map> map = this->map();
6088 6087
6089 while (map->prototype()->IsJSObject()) { 6088 while (map->prototype()->IsJSObject()) {
6090 holder_ = handle(JSObject::cast(map->prototype())); 6089 holder_ = handle(JSObject::cast(map->prototype()));
6091 if (holder_->map()->is_deprecated()) { 6090 if (holder_->map()->is_deprecated()) {
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
6540 DCHECK(instr->HasObservableSideEffects()); 6539 DCHECK(instr->HasObservableSideEffects());
6541 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6540 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6542 return; 6541 return;
6543 } 6542 }
6544 } 6543 }
6545 6544
6546 LookupIterator it(global, var->name(), LookupIterator::OWN); 6545 LookupIterator it(global, var->name(), LookupIterator::OWN);
6547 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 6546 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE);
6548 if (type == kUseCell) { 6547 if (type == kUseCell) {
6549 Handle<PropertyCell> cell = it.GetPropertyCell(); 6548 Handle<PropertyCell> cell = it.GetPropertyCell();
6550 PropertyCell::AddDependentCompilationInfo(cell, top_info()); 6549 top_info()->dependencies()->AssumePropertyCell(cell);
6551 if (it.property_details().cell_type() == PropertyCellType::kConstant) { 6550 if (it.property_details().cell_type() == PropertyCellType::kConstant) {
6552 Handle<Object> constant(cell->value(), isolate()); 6551 Handle<Object> constant(cell->value(), isolate());
6553 if (value->IsConstant()) { 6552 if (value->IsConstant()) {
6554 HConstant* c_value = HConstant::cast(value); 6553 HConstant* c_value = HConstant::cast(value);
6555 if (!constant.is_identical_to(c_value->handle(isolate()))) { 6554 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6556 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, 6555 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment,
6557 Deoptimizer::EAGER); 6556 Deoptimizer::EAGER);
6558 } 6557 }
6559 } else { 6558 } else {
6560 HValue* c_constant = Add<HConstant>(constant); 6559 HValue* c_constant = Add<HConstant>(constant);
(...skipping 2772 matching lines...) Expand 10 before | Expand all | Expand 10 after
9333 int argument_count, 9332 int argument_count,
9334 Handle<AllocationSite> site) { 9333 Handle<AllocationSite> site) {
9335 DCHECK(!site.is_null()); 9334 DCHECK(!site.is_null());
9336 DCHECK(argument_count >= 0 && argument_count <= 1); 9335 DCHECK(argument_count >= 0 && argument_count <= 1);
9337 NoObservableSideEffectsScope no_effects(this); 9336 NoObservableSideEffectsScope no_effects(this);
9338 9337
9339 // We should at least have the constructor on the expression stack. 9338 // We should at least have the constructor on the expression stack.
9340 HValue* constructor = environment()->ExpressionStackAt(argument_count); 9339 HValue* constructor = environment()->ExpressionStackAt(argument_count);
9341 9340
9342 // Register on the site for deoptimization if the transition feedback changes. 9341 // Register on the site for deoptimization if the transition feedback changes.
9343 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 9342 top_info()->dependencies()->AssumeTransitionStable(site);
9344 ElementsKind kind = site->GetElementsKind(); 9343 ElementsKind kind = site->GetElementsKind();
9345 HInstruction* site_instruction = Add<HConstant>(site); 9344 HInstruction* site_instruction = Add<HConstant>(site);
9346 9345
9347 // In the single constant argument case, we may have to adjust elements kind 9346 // In the single constant argument case, we may have to adjust elements kind
9348 // to avoid creating a packed non-empty array. 9347 // to avoid creating a packed non-empty array.
9349 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9348 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
9350 HValue* argument = environment()->Top(); 9349 HValue* argument = environment()->Top();
9351 if (argument->IsConstant()) { 9350 if (argument->IsConstant()) {
9352 HConstant* constant_argument = HConstant::cast(argument); 9351 HConstant* constant_argument = HConstant::cast(argument);
9353 DCHECK(constant_argument->HasSmiValue()); 9352 DCHECK(constant_argument->HasSmiValue());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
9469 9468
9470 // Allocate an instance of the implicit receiver object. 9469 // Allocate an instance of the implicit receiver object.
9471 HValue* size_in_bytes = Add<HConstant>(instance_size); 9470 HValue* size_in_bytes = Add<HConstant>(instance_size);
9472 HAllocationMode allocation_mode; 9471 HAllocationMode allocation_mode;
9473 if (FLAG_pretenuring_call_new) { 9472 if (FLAG_pretenuring_call_new) {
9474 if (FLAG_allocation_site_pretenuring) { 9473 if (FLAG_allocation_site_pretenuring) {
9475 // Try to use pretenuring feedback. 9474 // Try to use pretenuring feedback.
9476 Handle<AllocationSite> allocation_site = expr->allocation_site(); 9475 Handle<AllocationSite> allocation_site = expr->allocation_site();
9477 allocation_mode = HAllocationMode(allocation_site); 9476 allocation_mode = HAllocationMode(allocation_site);
9478 // Take a dependency on allocation site. 9477 // Take a dependency on allocation site.
9479 AllocationSite::RegisterForDeoptOnTenureChange(allocation_site, 9478 top_info()->dependencies()->AssumeTenuringDecision(allocation_site);
9480 top_info());
9481 } 9479 }
9482 } 9480 }
9483 9481
9484 HAllocate* receiver = BuildAllocate( 9482 HAllocate* receiver = BuildAllocate(
9485 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9483 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
9486 receiver->set_known_initial_map(initial_map); 9484 receiver->set_known_initial_map(initial_map);
9487 9485
9488 // Initialize map and fields of the newly allocated object. 9486 // Initialize map and fields of the newly allocated object.
9489 { NoObservableSideEffectsScope no_effects(this); 9487 { NoObservableSideEffectsScope no_effects(this);
9490 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); 9488 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE);
(...skipping 23 matching lines...) Expand all
9514 // Replace the constructor function with a newly allocated receiver using 9512 // Replace the constructor function with a newly allocated receiver using
9515 // the index of the receiver from the top of the expression stack. 9513 // the index of the receiver from the top of the expression stack.
9516 const int receiver_index = argument_count - 1; 9514 const int receiver_index = argument_count - 1;
9517 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); 9515 DCHECK(environment()->ExpressionStackAt(receiver_index) == function);
9518 environment()->SetExpressionStackAt(receiver_index, receiver); 9516 environment()->SetExpressionStackAt(receiver_index, receiver);
9519 9517
9520 if (TryInlineConstruct(expr, receiver)) { 9518 if (TryInlineConstruct(expr, receiver)) {
9521 // Inlining worked, add a dependency on the initial map to make sure that 9519 // Inlining worked, add a dependency on the initial map to make sure that
9522 // this code is deoptimized whenever the initial map of the constructor 9520 // this code is deoptimized whenever the initial map of the constructor
9523 // changes. 9521 // changes.
9524 Map::AddDependentCompilationInfo( 9522 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map);
9525 initial_map, DependentCode::kInitialMapChangedGroup, top_info());
9526 return; 9523 return;
9527 } 9524 }
9528 9525
9529 // TODO(mstarzinger): For now we remove the previous HAllocate and all 9526 // TODO(mstarzinger): For now we remove the previous HAllocate and all
9530 // corresponding instructions and instead add HPushArguments for the 9527 // corresponding instructions and instead add HPushArguments for the
9531 // arguments in case inlining failed. What we actually should do is for 9528 // arguments in case inlining failed. What we actually should do is for
9532 // inlining to try to build a subgraph without mutating the parent graph. 9529 // inlining to try to build a subgraph without mutating the parent graph.
9533 HInstruction* instr = current_block()->last(); 9530 HInstruction* instr = current_block()->last();
9534 do { 9531 do {
9535 HInstruction* prev_instr = instr->previous(); 9532 HInstruction* prev_instr = instr->previous();
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
10489 if (!left_string.is_null() && !right_string.is_null()) { 10486 if (!left_string.is_null() && !right_string.is_null()) {
10490 return AddUncasted<HStringAdd>( 10487 return AddUncasted<HStringAdd>(
10491 left, right, allocation_mode.GetPretenureMode(), 10488 left, right, allocation_mode.GetPretenureMode(),
10492 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10489 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
10493 } 10490 }
10494 10491
10495 // Register the dependent code with the allocation site. 10492 // Register the dependent code with the allocation site.
10496 if (!allocation_mode.feedback_site().is_null()) { 10493 if (!allocation_mode.feedback_site().is_null()) {
10497 DCHECK(!graph()->info()->IsStub()); 10494 DCHECK(!graph()->info()->IsStub());
10498 Handle<AllocationSite> site(allocation_mode.feedback_site()); 10495 Handle<AllocationSite> site(allocation_mode.feedback_site());
10499 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); 10496 top_info()->dependencies()->AssumeTenuringDecision(site);
10500 } 10497 }
10501 10498
10502 // Inline the string addition into the stub when creating allocation 10499 // Inline the string addition into the stub when creating allocation
10503 // mementos to gather allocation site feedback, or if we can statically 10500 // mementos to gather allocation site feedback, or if we can statically
10504 // infer that we're going to create a cons string. 10501 // infer that we're going to create a cons string.
10505 if ((graph()->info()->IsStub() && 10502 if ((graph()->info()->IsStub() &&
10506 allocation_mode.CreateAllocationMementos()) || 10503 allocation_mode.CreateAllocationMementos()) ||
10507 (left->IsConstant() && 10504 (left->IsConstant() &&
10508 HConstant::cast(left)->HasStringValue() && 10505 HConstant::cast(left)->HasStringValue() &&
10509 HConstant::cast(left)->StringValue()->length() + 1 >= 10506 HConstant::cast(left)->StringValue()->length() + 1 >=
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
11060 11057
11061 HType type = instance_type == JS_ARRAY_TYPE 11058 HType type = instance_type == JS_ARRAY_TYPE
11062 ? HType::JSArray() : HType::JSObject(); 11059 ? HType::JSArray() : HType::JSObject();
11063 HValue* object_size_constant = Add<HConstant>( 11060 HValue* object_size_constant = Add<HConstant>(
11064 boilerplate_object->map()->instance_size()); 11061 boilerplate_object->map()->instance_size());
11065 11062
11066 PretenureFlag pretenure_flag = NOT_TENURED; 11063 PretenureFlag pretenure_flag = NOT_TENURED;
11067 Handle<AllocationSite> site(site_context->current()); 11064 Handle<AllocationSite> site(site_context->current());
11068 if (FLAG_allocation_site_pretenuring) { 11065 if (FLAG_allocation_site_pretenuring) {
11069 pretenure_flag = site_context->current()->GetPretenureMode(); 11066 pretenure_flag = site_context->current()->GetPretenureMode();
11070 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); 11067 top_info()->dependencies()->AssumeTenuringDecision(site);
11071 } 11068 }
11072 11069
11073 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 11070 top_info()->dependencies()->AssumeTransitionStable(site);
11074 11071
11075 HInstruction* object = Add<HAllocate>(object_size_constant, type, 11072 HInstruction* object = Add<HAllocate>(object_size_constant, type,
11076 pretenure_flag, instance_type, site_context->current()); 11073 pretenure_flag, instance_type, site_context->current());
11077 11074
11078 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 11075 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
11079 // elements array may not get folded into the object. Hence, we set the 11076 // elements array may not get folded into the object. Hence, we set the
11080 // elements pointer to empty fixed array and let store elimination remove 11077 // elements pointer to empty fixed array and let store elimination remove
11081 // this store in the folding case. 11078 // this store in the folding case.
11082 HConstant* empty_fixed_array = Add<HConstant>( 11079 HConstant* empty_fixed_array = Add<HConstant>(
11083 isolate()->factory()->empty_fixed_array()); 11080 isolate()->factory()->empty_fixed_array());
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after
12948 if (ShouldProduceTraceOutput()) { 12945 if (ShouldProduceTraceOutput()) {
12949 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12946 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12950 } 12947 }
12951 12948
12952 #ifdef DEBUG 12949 #ifdef DEBUG
12953 graph_->Verify(false); // No full verify. 12950 graph_->Verify(false); // No full verify.
12954 #endif 12951 #endif
12955 } 12952 }
12956 12953
12957 } } // namespace v8::internal 12954 } } // namespace v8::internal
OLDNEW
« src/dependencies.cc ('K') | « src/hydrogen.h ('k') | src/lithium.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698