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

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
« no previous file with comments | « src/hydrogen.h ('k') | src/lithium.cc » ('j') | 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/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 5333 matching lines...) Expand 10 before | Expand all | Expand 10 after
5344 HObjectAccess::ForContextSlot(lookup.slot_index)); 5344 HObjectAccess::ForContextSlot(lookup.slot_index));
5345 return ast_context()->ReturnInstruction(result, expr->id()); 5345 return ast_context()->ReturnInstruction(result, expr->id());
5346 } 5346 }
5347 } 5347 }
5348 5348
5349 LookupIterator it(global, variable->name(), LookupIterator::OWN); 5349 LookupIterator it(global, variable->name(), LookupIterator::OWN);
5350 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); 5350 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD);
5351 5351
5352 if (type == kUseCell) { 5352 if (type == kUseCell) {
5353 Handle<PropertyCell> cell = it.GetPropertyCell(); 5353 Handle<PropertyCell> cell = it.GetPropertyCell();
5354 PropertyCell::AddDependentCompilationInfo(cell, top_info()); 5354 top_info()->dependencies()->AssumePropertyCell(cell);
5355 if (it.property_details().cell_type() == PropertyCellType::kConstant) { 5355 if (it.property_details().cell_type() == PropertyCellType::kConstant) {
5356 Handle<Object> constant_object(cell->value(), isolate()); 5356 Handle<Object> constant_object(cell->value(), isolate());
5357 if (constant_object->IsConsString()) { 5357 if (constant_object->IsConsString()) {
5358 constant_object = 5358 constant_object =
5359 String::Flatten(Handle<String>::cast(constant_object)); 5359 String::Flatten(Handle<String>::cast(constant_object));
5360 } 5360 }
5361 HConstant* constant = New<HConstant>(constant_object); 5361 HConstant* constant = New<HConstant>(constant_object);
5362 return ast_context()->ReturnInstruction(constant, expr->id()); 5362 return ast_context()->ReturnInstruction(constant, expr->id());
5363 } else { 5363 } else {
5364 HConstant* cell_constant = Add<HConstant>(cell); 5364 HConstant* cell_constant = Add<HConstant>(cell);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
5725 Add<HConstant>(literal_index), 5725 Add<HConstant>(literal_index),
5726 Add<HConstant>(constants), 5726 Add<HConstant>(constants),
5727 Add<HConstant>(flags)); 5727 Add<HConstant>(flags));
5728 5728
5729 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5729 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
5730 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5730 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5731 Runtime::FunctionForId(function_id), 5731 Runtime::FunctionForId(function_id),
5732 4); 5732 4);
5733 5733
5734 // Register to deopt if the boilerplate ElementsKind changes. 5734 // Register to deopt if the boilerplate ElementsKind changes.
5735 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 5735 top_info()->dependencies()->AssumeTransitionStable(site);
5736 } 5736 }
5737 5737
5738 // The array is expected in the bailout environment during computation 5738 // The array is expected in the bailout environment during computation
5739 // of the property values and is the value of the entire expression. 5739 // of the property values and is the value of the entire expression.
5740 Push(literal); 5740 Push(literal);
5741 // The literal index is on the stack, too. 5741 // The literal index is on the stack, too.
5742 Push(Add<HConstant>(expr->literal_index())); 5742 Push(Add<HConstant>(expr->literal_index()));
5743 5743
5744 HInstruction* elements = NULL; 5744 HInstruction* elements = NULL;
5745 5745
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
6040 } 6040 }
6041 6041
6042 field_maps_.Sort(); 6042 field_maps_.Sort();
6043 DCHECK_EQ(num_field_maps, field_maps_.length()); 6043 DCHECK_EQ(num_field_maps, field_maps_.length());
6044 6044
6045 // Determine field HType from field HeapType. 6045 // Determine field HType from field HeapType.
6046 field_type_ = HType::FromType<HeapType>(field_type); 6046 field_type_ = HType::FromType<HeapType>(field_type);
6047 DCHECK(field_type_.IsHeapObject()); 6047 DCHECK(field_type_.IsHeapObject());
6048 6048
6049 // Add dependency on the map that introduced the field. 6049 // Add dependency on the map that introduced the field.
6050 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), 6050 top_info()->dependencies()->AssumeFieldType(GetFieldOwnerFromMap(map));
6051 DependentCode::kFieldTypeGroup, top_info());
6052 return true; 6051 return true;
6053 } 6052 }
6054 6053
6055 6054
6056 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 6055 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
6057 Handle<Map> map = this->map(); 6056 Handle<Map> map = this->map();
6058 6057
6059 while (map->prototype()->IsJSObject()) { 6058 while (map->prototype()->IsJSObject()) {
6060 holder_ = handle(JSObject::cast(map->prototype())); 6059 holder_ = handle(JSObject::cast(map->prototype()));
6061 if (holder_->map()->is_deprecated()) { 6060 if (holder_->map()->is_deprecated()) {
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
6510 DCHECK(instr->HasObservableSideEffects()); 6509 DCHECK(instr->HasObservableSideEffects());
6511 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6510 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6512 return; 6511 return;
6513 } 6512 }
6514 } 6513 }
6515 6514
6516 LookupIterator it(global, var->name(), LookupIterator::OWN); 6515 LookupIterator it(global, var->name(), LookupIterator::OWN);
6517 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE); 6516 GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE);
6518 if (type == kUseCell) { 6517 if (type == kUseCell) {
6519 Handle<PropertyCell> cell = it.GetPropertyCell(); 6518 Handle<PropertyCell> cell = it.GetPropertyCell();
6520 PropertyCell::AddDependentCompilationInfo(cell, top_info()); 6519 top_info()->dependencies()->AssumePropertyCell(cell);
6521 if (it.property_details().cell_type() == PropertyCellType::kConstant) { 6520 if (it.property_details().cell_type() == PropertyCellType::kConstant) {
6522 Handle<Object> constant(cell->value(), isolate()); 6521 Handle<Object> constant(cell->value(), isolate());
6523 if (value->IsConstant()) { 6522 if (value->IsConstant()) {
6524 HConstant* c_value = HConstant::cast(value); 6523 HConstant* c_value = HConstant::cast(value);
6525 if (!constant.is_identical_to(c_value->handle(isolate()))) { 6524 if (!constant.is_identical_to(c_value->handle(isolate()))) {
6526 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, 6525 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment,
6527 Deoptimizer::EAGER); 6526 Deoptimizer::EAGER);
6528 } 6527 }
6529 } else { 6528 } else {
6530 HValue* c_constant = Add<HConstant>(constant); 6529 HValue* c_constant = Add<HConstant>(constant);
(...skipping 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after
9304 int argument_count, 9303 int argument_count,
9305 Handle<AllocationSite> site) { 9304 Handle<AllocationSite> site) {
9306 DCHECK(!site.is_null()); 9305 DCHECK(!site.is_null());
9307 DCHECK(argument_count >= 0 && argument_count <= 1); 9306 DCHECK(argument_count >= 0 && argument_count <= 1);
9308 NoObservableSideEffectsScope no_effects(this); 9307 NoObservableSideEffectsScope no_effects(this);
9309 9308
9310 // We should at least have the constructor on the expression stack. 9309 // We should at least have the constructor on the expression stack.
9311 HValue* constructor = environment()->ExpressionStackAt(argument_count); 9310 HValue* constructor = environment()->ExpressionStackAt(argument_count);
9312 9311
9313 // Register on the site for deoptimization if the transition feedback changes. 9312 // Register on the site for deoptimization if the transition feedback changes.
9314 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 9313 top_info()->dependencies()->AssumeTransitionStable(site);
9315 ElementsKind kind = site->GetElementsKind(); 9314 ElementsKind kind = site->GetElementsKind();
9316 HInstruction* site_instruction = Add<HConstant>(site); 9315 HInstruction* site_instruction = Add<HConstant>(site);
9317 9316
9318 // In the single constant argument case, we may have to adjust elements kind 9317 // In the single constant argument case, we may have to adjust elements kind
9319 // to avoid creating a packed non-empty array. 9318 // to avoid creating a packed non-empty array.
9320 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9319 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
9321 HValue* argument = environment()->Top(); 9320 HValue* argument = environment()->Top();
9322 if (argument->IsConstant()) { 9321 if (argument->IsConstant()) {
9323 HConstant* constant_argument = HConstant::cast(argument); 9322 HConstant* constant_argument = HConstant::cast(argument);
9324 DCHECK(constant_argument->HasSmiValue()); 9323 DCHECK(constant_argument->HasSmiValue());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
9440 9439
9441 // Allocate an instance of the implicit receiver object. 9440 // Allocate an instance of the implicit receiver object.
9442 HValue* size_in_bytes = Add<HConstant>(instance_size); 9441 HValue* size_in_bytes = Add<HConstant>(instance_size);
9443 HAllocationMode allocation_mode; 9442 HAllocationMode allocation_mode;
9444 if (FLAG_pretenuring_call_new) { 9443 if (FLAG_pretenuring_call_new) {
9445 if (FLAG_allocation_site_pretenuring) { 9444 if (FLAG_allocation_site_pretenuring) {
9446 // Try to use pretenuring feedback. 9445 // Try to use pretenuring feedback.
9447 Handle<AllocationSite> allocation_site = expr->allocation_site(); 9446 Handle<AllocationSite> allocation_site = expr->allocation_site();
9448 allocation_mode = HAllocationMode(allocation_site); 9447 allocation_mode = HAllocationMode(allocation_site);
9449 // Take a dependency on allocation site. 9448 // Take a dependency on allocation site.
9450 AllocationSite::RegisterForDeoptOnTenureChange(allocation_site, 9449 top_info()->dependencies()->AssumeTenuringDecision(allocation_site);
9451 top_info());
9452 } 9450 }
9453 } 9451 }
9454 9452
9455 HAllocate* receiver = BuildAllocate( 9453 HAllocate* receiver = BuildAllocate(
9456 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9454 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
9457 receiver->set_known_initial_map(initial_map); 9455 receiver->set_known_initial_map(initial_map);
9458 9456
9459 // Initialize map and fields of the newly allocated object. 9457 // Initialize map and fields of the newly allocated object.
9460 { NoObservableSideEffectsScope no_effects(this); 9458 { NoObservableSideEffectsScope no_effects(this);
9461 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); 9459 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE);
(...skipping 23 matching lines...) Expand all
9485 // Replace the constructor function with a newly allocated receiver using 9483 // Replace the constructor function with a newly allocated receiver using
9486 // the index of the receiver from the top of the expression stack. 9484 // the index of the receiver from the top of the expression stack.
9487 const int receiver_index = argument_count - 1; 9485 const int receiver_index = argument_count - 1;
9488 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); 9486 DCHECK(environment()->ExpressionStackAt(receiver_index) == function);
9489 environment()->SetExpressionStackAt(receiver_index, receiver); 9487 environment()->SetExpressionStackAt(receiver_index, receiver);
9490 9488
9491 if (TryInlineConstruct(expr, receiver)) { 9489 if (TryInlineConstruct(expr, receiver)) {
9492 // Inlining worked, add a dependency on the initial map to make sure that 9490 // Inlining worked, add a dependency on the initial map to make sure that
9493 // this code is deoptimized whenever the initial map of the constructor 9491 // this code is deoptimized whenever the initial map of the constructor
9494 // changes. 9492 // changes.
9495 Map::AddDependentCompilationInfo( 9493 top_info()->dependencies()->AssumeInitialMapCantChange(initial_map);
9496 initial_map, DependentCode::kInitialMapChangedGroup, top_info());
9497 return; 9494 return;
9498 } 9495 }
9499 9496
9500 // TODO(mstarzinger): For now we remove the previous HAllocate and all 9497 // TODO(mstarzinger): For now we remove the previous HAllocate and all
9501 // corresponding instructions and instead add HPushArguments for the 9498 // corresponding instructions and instead add HPushArguments for the
9502 // arguments in case inlining failed. What we actually should do is for 9499 // arguments in case inlining failed. What we actually should do is for
9503 // inlining to try to build a subgraph without mutating the parent graph. 9500 // inlining to try to build a subgraph without mutating the parent graph.
9504 HInstruction* instr = current_block()->last(); 9501 HInstruction* instr = current_block()->last();
9505 do { 9502 do {
9506 HInstruction* prev_instr = instr->previous(); 9503 HInstruction* prev_instr = instr->previous();
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
10460 if (!left_string.is_null() && !right_string.is_null()) { 10457 if (!left_string.is_null() && !right_string.is_null()) {
10461 return AddUncasted<HStringAdd>( 10458 return AddUncasted<HStringAdd>(
10462 left, right, allocation_mode.GetPretenureMode(), 10459 left, right, allocation_mode.GetPretenureMode(),
10463 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10460 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
10464 } 10461 }
10465 10462
10466 // Register the dependent code with the allocation site. 10463 // Register the dependent code with the allocation site.
10467 if (!allocation_mode.feedback_site().is_null()) { 10464 if (!allocation_mode.feedback_site().is_null()) {
10468 DCHECK(!graph()->info()->IsStub()); 10465 DCHECK(!graph()->info()->IsStub());
10469 Handle<AllocationSite> site(allocation_mode.feedback_site()); 10466 Handle<AllocationSite> site(allocation_mode.feedback_site());
10470 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); 10467 top_info()->dependencies()->AssumeTenuringDecision(site);
10471 } 10468 }
10472 10469
10473 // Inline the string addition into the stub when creating allocation 10470 // Inline the string addition into the stub when creating allocation
10474 // mementos to gather allocation site feedback, or if we can statically 10471 // mementos to gather allocation site feedback, or if we can statically
10475 // infer that we're going to create a cons string. 10472 // infer that we're going to create a cons string.
10476 if ((graph()->info()->IsStub() && 10473 if ((graph()->info()->IsStub() &&
10477 allocation_mode.CreateAllocationMementos()) || 10474 allocation_mode.CreateAllocationMementos()) ||
10478 (left->IsConstant() && 10475 (left->IsConstant() &&
10479 HConstant::cast(left)->HasStringValue() && 10476 HConstant::cast(left)->HasStringValue() &&
10480 HConstant::cast(left)->StringValue()->length() + 1 >= 10477 HConstant::cast(left)->StringValue()->length() + 1 >=
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
11031 11028
11032 HType type = instance_type == JS_ARRAY_TYPE 11029 HType type = instance_type == JS_ARRAY_TYPE
11033 ? HType::JSArray() : HType::JSObject(); 11030 ? HType::JSArray() : HType::JSObject();
11034 HValue* object_size_constant = Add<HConstant>( 11031 HValue* object_size_constant = Add<HConstant>(
11035 boilerplate_object->map()->instance_size()); 11032 boilerplate_object->map()->instance_size());
11036 11033
11037 PretenureFlag pretenure_flag = NOT_TENURED; 11034 PretenureFlag pretenure_flag = NOT_TENURED;
11038 Handle<AllocationSite> site(site_context->current()); 11035 Handle<AllocationSite> site(site_context->current());
11039 if (FLAG_allocation_site_pretenuring) { 11036 if (FLAG_allocation_site_pretenuring) {
11040 pretenure_flag = site_context->current()->GetPretenureMode(); 11037 pretenure_flag = site_context->current()->GetPretenureMode();
11041 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); 11038 top_info()->dependencies()->AssumeTenuringDecision(site);
11042 } 11039 }
11043 11040
11044 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); 11041 top_info()->dependencies()->AssumeTransitionStable(site);
11045 11042
11046 HInstruction* object = Add<HAllocate>(object_size_constant, type, 11043 HInstruction* object = Add<HAllocate>(object_size_constant, type,
11047 pretenure_flag, instance_type, site_context->current()); 11044 pretenure_flag, instance_type, site_context->current());
11048 11045
11049 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the 11046 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
11050 // elements array may not get folded into the object. Hence, we set the 11047 // elements array may not get folded into the object. Hence, we set the
11051 // elements pointer to empty fixed array and let store elimination remove 11048 // elements pointer to empty fixed array and let store elimination remove
11052 // this store in the folding case. 11049 // this store in the folding case.
11053 HConstant* empty_fixed_array = Add<HConstant>( 11050 HConstant* empty_fixed_array = Add<HConstant>(
11054 isolate()->factory()->empty_fixed_array()); 11051 isolate()->factory()->empty_fixed_array());
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after
12919 if (ShouldProduceTraceOutput()) { 12916 if (ShouldProduceTraceOutput()) {
12920 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12917 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12921 } 12918 }
12922 12919
12923 #ifdef DEBUG 12920 #ifdef DEBUG
12924 graph_->Verify(false); // No full verify. 12921 graph_->Verify(false); // No full verify.
12925 #endif 12922 #endif
12926 } 12923 }
12927 12924
12928 } } // namespace v8::internal 12925 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/lithium.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698