Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
index 0de6dac..9c5fa15 100644
--- a/src/crankshaft/hydrogen.cc
+++ b/src/crankshaft/hydrogen.cc
@@ -68,6 +68,177 @@
namespace v8 {
namespace internal {
+class HOptimizedGraphBuilderWithPositions : public HOptimizedGraphBuilder {
+ public:
+ explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info)
+ : HOptimizedGraphBuilder(info) {}
+
+#define DEF_VISIT(type) \
+ void Visit##type(type* node) override { \
+ SourcePosition old_position = SourcePosition::Unknown(); \
+ if (node->position() != RelocInfo::kNoPosition) { \
+ old_position = source_position(); \
+ SetSourcePosition(node->position()); \
+ } \
+ HOptimizedGraphBuilder::Visit##type(node); \
+ if (!old_position.IsUnknown()) { \
+ set_source_position(old_position); \
+ } \
+ }
+ EXPRESSION_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
+
+#define DEF_VISIT(type) \
+ void Visit##type(type* node) override { \
+ SourcePosition old_position = SourcePosition::Unknown(); \
+ if (node->position() != RelocInfo::kNoPosition) { \
+ old_position = source_position(); \
+ SetSourcePosition(node->position()); \
+ } \
+ HOptimizedGraphBuilder::Visit##type(node); \
+ if (!old_position.IsUnknown()) { \
+ set_source_position(old_position); \
+ } \
+ }
+ STATEMENT_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
+
+#define DEF_VISIT(type) \
+ void Visit##type(type* node) override { \
+ HOptimizedGraphBuilder::Visit##type(node); \
+ }
+ DECLARATION_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
+};
+
+HCompilationJob::Status HCompilationJob::CreateGraphImpl() {
+ bool dont_crankshaft = info()->shared_info()->dont_crankshaft();
+
+ // Optimization requires a version of fullcode with deoptimization support.
+ // Recompile the unoptimized version of the code if the current version
+ // doesn't have deoptimization support already.
+ // Otherwise, if we are gathering compilation time and space statistics
+ // for hydrogen, gather baseline statistics for a fullcode compilation.
+ bool should_recompile = !info()->shared_info()->has_deoptimization_support();
+ if (should_recompile || FLAG_hydrogen_stats) {
+ base::ElapsedTimer timer;
+ if (FLAG_hydrogen_stats) {
+ timer.Start();
+ }
+ if (!Compiler::EnsureDeoptimizationSupport(info())) {
+ return FAILED;
+ }
+ if (FLAG_hydrogen_stats) {
+ isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed());
+ }
+ }
+ DCHECK(info()->shared_info()->has_deoptimization_support());
+ DCHECK(!info()->shared_info()->never_compiled());
+
+ if (!isolate()->use_crankshaft() || dont_crankshaft) {
+ // Crankshaft is entirely disabled.
+ return FAILED;
+ }
+
+ // Check the whitelist for Crankshaft.
+ if (!info()->shared_info()->PassesFilter(FLAG_hydrogen_filter)) {
+ return AbortOptimization(kHydrogenFilter);
+ }
+
+ Scope* scope = info()->scope();
+ if (LUnallocated::TooManyParameters(scope->num_parameters())) {
+ // Crankshaft would require too many Lithium operands.
+ return AbortOptimization(kTooManyParameters);
+ }
+
+ if (info()->is_osr() &&
+ LUnallocated::TooManyParametersOrStackSlots(scope->num_parameters(),
+ scope->num_stack_slots())) {
+ // Crankshaft would require too many Lithium operands.
+ return AbortOptimization(kTooManyParametersLocals);
+ }
+
+ if (IsGeneratorFunction(info()->shared_info()->kind())) {
+ // Crankshaft does not support generators.
+ return AbortOptimization(kGenerator);
+ }
+
+ if (FLAG_trace_hydrogen) {
+ isolate()->GetHTracer()->TraceCompilation(info());
+ }
+
+ // Optimization could have been disabled by the parser. Note that this check
+ // is only needed because the Hydrogen graph builder is missing some bailouts.
+ if (info()->shared_info()->optimization_disabled()) {
+ return AbortOptimization(
+ info()->shared_info()->disable_optimization_reason());
+ }
+
+ HOptimizedGraphBuilder* graph_builder =
+ (info()->is_tracking_positions() || FLAG_trace_ic)
+ ? new (info()->zone()) HOptimizedGraphBuilderWithPositions(info())
+ : new (info()->zone()) HOptimizedGraphBuilder(info());
+
+ // Type-check the function.
+ AstTyper(info()->isolate(), info()->zone(), info()->closure(),
+ info()->scope(), info()->osr_ast_id(), info()->literal(),
+ graph_builder->bounds())
+ .Run();
+
+ graph_ = graph_builder->CreateGraph();
+
+ if (isolate()->has_pending_exception()) {
+ return FAILED;
+ }
+
+ if (graph_ == NULL) return FAILED;
+
+ if (info()->dependencies()->HasAborted()) {
+ // Dependency has changed during graph creation. Let's try again later.
+ return RetryOptimization(kBailedOutDueToDependencyChange);
+ }
+
+ return SUCCEEDED;
+}
+
+HCompilationJob::Status HCompilationJob::OptimizeGraphImpl() {
+ DCHECK(graph_ != NULL);
+ BailoutReason bailout_reason = kNoReason;
+
+ if (graph_->Optimize(&bailout_reason)) {
+ chunk_ = LChunk::NewChunk(graph_);
+ if (chunk_ != NULL) return SUCCEEDED;
+ } else if (bailout_reason != kNoReason) {
+ info()->AbortOptimization(bailout_reason);
+ }
+
+ return FAILED;
+}
+
+HCompilationJob::Status HCompilationJob::GenerateCodeImpl() {
+ DCHECK(chunk_ != NULL);
+ DCHECK(graph_ != NULL);
+ {
+ // Deferred handles reference objects that were accessible during
+ // graph creation. To make sure that we don't encounter inconsistencies
+ // between graph creation and code generation, we disallow accessing
+ // objects through deferred handles during the latter, with exceptions.
+ DisallowDeferredHandleDereference no_deferred_handle_deref;
+ Handle<Code> optimized_code = chunk_->Codegen();
+ if (optimized_code.is_null()) {
+ if (info()->bailout_reason() == kNoReason) {
+ return AbortOptimization(kCodeGenerationFailed);
+ }
+ return FAILED;
+ }
+ RegisterWeakObjectsInOptimizedCode(optimized_code);
+ info()->SetCode(optimized_code);
+ }
+ // Add to the weak list of optimized code objects.
+ info()->context()->native_context()->AddOptimizedCode(*info()->code());
+ return SUCCEEDED;
+}
+
HBasicBlock::HBasicBlock(HGraph* graph)
: block_id_(graph->GetNextBlockID()),
graph_(graph),
@@ -1188,6 +1359,9 @@
HGraph* HGraphBuilder::CreateGraph() {
graph_ = new (zone()) HGraph(info_, descriptor_);
if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
+ if (!info_->IsStub() && info_->is_tracking_positions()) {
+ TraceInlinedFunction(info_->shared_info(), SourcePosition::Unknown());
+ }
CompilationPhase phase("H_Block building", info_);
set_current_block(graph()->entry_block());
if (!BuildGraph()) return NULL;
@@ -1195,6 +1369,52 @@
return graph_;
}
+int HGraphBuilder::TraceInlinedFunction(Handle<SharedFunctionInfo> shared,
+ SourcePosition position) {
+ DCHECK(info_->is_tracking_positions());
+
+ int inline_id = static_cast<int>(graph()->inlined_function_infos().size());
+ HInlinedFunctionInfo info(shared->start_position());
+ if (!shared->script()->IsUndefined()) {
+ Handle<Script> script(Script::cast(shared->script()));
+
+ if (FLAG_hydrogen_track_positions && !script->source()->IsUndefined()) {
+ CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
+ Object* source_name = script->name();
+ OFStream os(tracing_scope.file());
+ os << "--- FUNCTION SOURCE (";
+ if (source_name->IsString()) {
+ os << String::cast(source_name)->ToCString().get() << ":";
+ }
+ os << shared->DebugName()->ToCString().get() << ") id{";
+ os << info_->optimization_id() << "," << inline_id << "} ---\n";
+ {
+ DisallowHeapAllocation no_allocation;
+ int start = shared->start_position();
+ int len = shared->end_position() - start;
+ String::SubStringRange source(String::cast(script->source()), start,
+ len);
+ for (const auto& c : source) {
+ os << AsReversiblyEscapedUC16(c);
+ }
+ }
+
+ os << "\n--- END ---\n";
+ }
+ }
+
+ graph()->inlined_function_infos().push_back(info);
+
+ if (FLAG_hydrogen_track_positions && inline_id != 0) {
+ CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
+ OFStream os(tracing_scope.file());
+ os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{"
+ << info_->optimization_id() << "," << inline_id << "} AS " << inline_id
+ << " AT " << position << std::endl;
+ }
+
+ return inline_id;
+}
HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
DCHECK(current_block() != NULL);
@@ -1822,7 +2042,7 @@
// Allocate the JSIteratorResult object.
HValue* result =
Add<HAllocate>(Add<HConstant>(JSIteratorResult::kSize), HType::JSObject(),
- NOT_TENURED, JS_OBJECT_TYPE);
+ NOT_TENURED, JS_OBJECT_TYPE, graph()->GetConstant0());
// Initialize the JSIteratorResult object.
HValue* native_context = BuildGetNativeContext();
@@ -1859,9 +2079,9 @@
HValue* size = BuildCalculateElementsSize(elements_kind, length);
// Allocate the JSRegExpResult and the FixedArray in one step.
- HValue* result = Add<HAllocate>(
- Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(),
- NOT_TENURED, JS_ARRAY_TYPE);
+ HValue* result =
+ Add<HAllocate>(Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(),
+ NOT_TENURED, JS_ARRAY_TYPE, graph()->GetConstant0());
// Initialize the JSRegExpResult header.
HValue* native_context = Add<HLoadNamedField>(
@@ -1895,12 +2115,6 @@
HAllocate* elements = BuildAllocateElements(elements_kind, size);
BuildInitializeElementsHeader(elements, elements_kind, length);
- if (!elements->has_size_upper_bound()) {
- HConstant* size_in_bytes_upper_bound = EstablishElementsAllocationSize(
- elements_kind, max_length->Integer32Value());
- elements->set_size_upper_bound(size_in_bytes_upper_bound);
- }
-
Add<HStoreNamedField>(
result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset),
elements);
@@ -2062,9 +2276,8 @@
Callable callable = CodeFactory::ToNumber(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context(), input};
- HCallWithDescriptor* instr =
- Add<HCallWithDescriptor>(stub, 0, callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HCallWithDescriptor* instr = Add<HCallWithDescriptor>(
+ stub, 0, callable.descriptor(), ArrayVector(values));
instr->set_type(HType::TaggedNumber());
return instr;
}
@@ -2177,8 +2390,8 @@
// Perform the actual allocation.
HAllocate* object = Add<HAllocate>(
- size, type, allocation_mode.GetPretenureMode(),
- instance_type, allocation_mode.feedback_site());
+ size, type, allocation_mode.GetPretenureMode(), instance_type,
+ graph()->GetConstant0(), allocation_mode.feedback_site());
// Setup the allocation memento.
if (allocation_mode.CreateAllocationMementos()) {
@@ -2673,7 +2886,6 @@
return array_builder->AllocateEmptyArray();
} else {
return array_builder->AllocateArray(length_argument,
- array_length,
length_argument);
}
}
@@ -2706,7 +2918,7 @@
// Figure out total size
HValue* length = Pop();
HValue* capacity = Pop();
- return array_builder->AllocateArray(capacity, max_alloc_length, length);
+ return array_builder->AllocateArray(capacity, length);
}
@@ -2738,8 +2950,8 @@
base_size += AllocationMemento::kSize;
}
HConstant* size_in_bytes = Add<HConstant>(base_size);
- return Add<HAllocate>(
- size_in_bytes, HType::JSArray(), NOT_TENURED, JS_OBJECT_TYPE);
+ return Add<HAllocate>(size_in_bytes, HType::JSArray(), NOT_TENURED,
+ JS_OBJECT_TYPE, graph()->GetConstant0());
}
@@ -2761,7 +2973,7 @@
: FIXED_ARRAY_TYPE;
return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED,
- instance_type);
+ instance_type, graph()->GetConstant0());
}
@@ -3149,14 +3361,6 @@
HAllocate* elements = BuildAllocateElements(kind, elements_size);
- // This function implicitly relies on the fact that the
- // FastCloneShallowArrayStub is called only for literals shorter than
- // JSArray::kInitialMaxFastElementArray.
- // Can't add HBoundsCheck here because otherwise the stub will eager a frame.
- HConstant* size_upper_bound = EstablishElementsAllocationSize(
- kind, JSArray::kInitialMaxFastElementArray);
- elements->set_size_upper_bound(size_upper_bound);
-
Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements);
// The allocation for the cloned array above causes register pressure on
@@ -3396,42 +3600,12 @@
HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
return AllocateArray(capacity,
- capacity,
builder()->graph()->GetConstant0());
}
HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
HValue* capacity,
- HConstant* capacity_upper_bound,
- HValue* length_field,
- FillMode fill_mode) {
- return AllocateArray(capacity,
- capacity_upper_bound->GetInteger32Constant(),
- length_field,
- fill_mode);
-}
-
-
-HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
- HValue* capacity,
- int capacity_upper_bound,
- HValue* length_field,
- FillMode fill_mode) {
- HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant()
- ? HConstant::cast(capacity)
- : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound);
-
- HAllocate* array = AllocateArray(capacity, length_field, fill_mode);
- if (!elements_location_->has_size_upper_bound()) {
- elements_location_->set_size_upper_bound(elememts_size_upper_bound);
- }
- return array;
-}
-
-
-HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray(
- HValue* capacity,
HValue* length_field,
FillMode fill_mode) {
// These HForceRepresentations are because we store these as fields in the
@@ -3506,7 +3680,8 @@
break_scope_(NULL),
inlined_count_(0),
globals_(10, info->zone()),
- osr_(new (info->zone()) HOsrBuilder(this)) {
+ osr_(new (info->zone()) HOsrBuilder(this)),
+ bounds_(info->zone()) {
// This is not initialized in the initializer list because the
// constructor for the initial state relies on function_state_ == NULL
// to know it's the initial state.
@@ -3599,7 +3774,6 @@
return os << "B" << b.block_id();
}
-
HGraph::HGraph(CompilationInfo* info, CallInterfaceDescriptor descriptor)
: isolate_(info->isolate()),
next_block_id_(0),
@@ -3612,21 +3786,19 @@
info_(info),
descriptor_(descriptor),
zone_(info->zone()),
+ allow_code_motion_(false),
use_optimistic_licm_(false),
depends_on_empty_array_proto_elements_(false),
type_change_checksum_(0),
maximum_environment_size_(0),
no_side_effects_scope_count_(0),
- disallow_adding_new_values_(false) {
+ disallow_adding_new_values_(false),
+ inlined_function_infos_(info->zone()) {
if (info->IsStub()) {
// For stubs, explicitly add the context to the environment.
start_environment_ = new (zone_)
HEnvironment(zone_, descriptor.GetRegisterParameterCount() + 1);
} else {
- if (info->is_tracking_positions()) {
- info->TraceInlinedFunction(info->shared_info(), SourcePosition::Unknown(),
- InlinedFunctionInfo::kNoParentId);
- }
start_environment_ =
new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
}
@@ -3655,7 +3827,8 @@
int HGraph::SourcePositionToScriptPosition(SourcePosition pos) {
return (FLAG_hydrogen_track_positions && !pos.IsUnknown())
- ? info()->start_position_for(pos.inlining_id()) + pos.position()
+ ? inlined_function_infos_.at(pos.inlining_id()).start_position +
+ pos.position()
: pos.raw();
}
@@ -4445,6 +4618,11 @@
!type_info->matches_inlined_type_change_checksum(composite_checksum));
type_info->set_inlined_type_change_checksum(composite_checksum);
+ // Set this predicate early to avoid handle deref during graph optimization.
+ graph()->set_allow_code_motion(
+ current_info()->IsStub() ||
+ current_info()->shared_info()->opt_count() + 1 < FLAG_max_opt_count);
+
// Perform any necessary OSR-specific cleanups or changes to the graph.
osr()->FinishGraph();
@@ -4991,7 +5169,7 @@
CHECK_ALIVE(VisitForValue(stmt->tag()));
Add<HSimulate>(stmt->EntryId());
HValue* tag_value = Top();
- Type* tag_type = stmt->tag()->bounds().lower;
+ Type* tag_type = bounds_.get(stmt->tag()).lower;
// 1. Build all the tests, with dangling true branches
BailoutId default_id = BailoutId::None();
@@ -5008,7 +5186,7 @@
if (current_block() == NULL) return Bailout(kUnsupportedSwitchStatement);
HValue* label_value = Pop();
- Type* label_type = clause->label()->bounds().lower;
+ Type* label_type = bounds_.get(clause->label()).lower;
Type* combined_type = clause->compare_type();
HControlInstruction* compare = BuildCompareInstruction(
Token::EQ_STRICT, tag_value, label_value, tag_type, label_type,
@@ -5500,8 +5678,8 @@
FastNewClosureDescriptor descriptor(isolate());
HValue* values[] = {context(), shared_info_value};
HConstant* stub_value = Add<HConstant>(stub.GetCode());
- instr = New<HCallWithDescriptor>(
- stub_value, 0, descriptor, Vector<HValue*>(values, arraysize(values)));
+ instr = New<HCallWithDescriptor>(stub_value, 0, descriptor,
+ ArrayVector(values));
} else {
Add<HPushArguments>(shared_info_value);
Runtime::FunctionId function_id =
@@ -5593,6 +5771,7 @@
return kUseGeneric;
case LookupIterator::DATA:
if (access_type == STORE && it->IsReadOnly()) return kUseGeneric;
+ if (!it->GetHolder<JSObject>()->IsJSGlobalObject()) return kUseGeneric;
return kUseCell;
case LookupIterator::JSPROXY:
case LookupIterator::TRANSITION:
@@ -5746,9 +5925,6 @@
case CONST:
mode = HLoadContextSlot::kCheckDeoptimize;
break;
- case CONST_LEGACY:
- mode = HLoadContextSlot::kCheckReturnUndefined;
- break;
default:
mode = HLoadContextSlot::kNoCheck;
break;
@@ -5782,9 +5958,8 @@
context(), AddThisFunction(), Add<HConstant>(expr->literal_index()),
Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())};
HConstant* stub_value = Add<HConstant>(callable.code());
- HInstruction* instr =
- New<HCallWithDescriptor>(stub_value, 0, callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* instr = New<HCallWithDescriptor>(
+ stub_value, 0, callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(instr, expr->id());
}
@@ -5995,59 +6170,29 @@
Handle<AllocationSite> site;
Handle<LiteralsArray> literals(environment()->closure()->literals(),
isolate());
- bool uninitialized = false;
Handle<Object> literals_cell(literals->literal(expr->literal_index()),
isolate());
Handle<JSObject> boilerplate_object;
- if (literals_cell->IsUndefined()) {
- uninitialized = true;
- Handle<Object> raw_boilerplate;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate(), raw_boilerplate,
- Runtime::CreateArrayLiteralBoilerplate(isolate(), literals,
- expr->constant_elements()),
- Bailout(kArrayBoilerplateCreationFailed));
-
- boilerplate_object = Handle<JSObject>::cast(raw_boilerplate);
- AllocationSiteCreationContext creation_context(isolate());
- site = creation_context.EnterNewScope();
- if (JSObject::DeepWalk(boilerplate_object, &creation_context).is_null()) {
- return Bailout(kArrayBoilerplateCreationFailed);
- }
- creation_context.ExitScope(site, boilerplate_object);
- literals->set_literal(expr->literal_index(), *site);
-
- if (boilerplate_object->elements()->map() ==
- isolate()->heap()->fixed_cow_array_map()) {
- isolate()->counters()->cow_arrays_created_runtime()->Increment();
- }
- } else {
+ if (!literals_cell->IsUndefined()) {
DCHECK(literals_cell->IsAllocationSite());
site = Handle<AllocationSite>::cast(literals_cell);
boilerplate_object = Handle<JSObject>(
JSObject::cast(site->transition_info()), isolate());
}
- DCHECK(!boilerplate_object.is_null());
- DCHECK(site->SitePointsToLiteral());
-
- ElementsKind boilerplate_elements_kind =
- boilerplate_object->GetElementsKind();
-
// Check whether to use fast or slow deep-copying for boilerplate.
int max_properties = kMaxFastLiteralProperties;
- if (IsFastLiteral(boilerplate_object,
- kMaxFastLiteralDepth,
+ if (!boilerplate_object.is_null() &&
+ IsFastLiteral(boilerplate_object, kMaxFastLiteralDepth,
&max_properties)) {
+ DCHECK(site->SitePointsToLiteral());
AllocationSiteUsageContext site_context(isolate(), site, false);
site_context.EnterNewScope();
literal = BuildFastLiteral(boilerplate_object, &site_context);
site_context.ExitScope(site, boilerplate_object);
} else {
NoObservableSideEffectsScope no_effects(this);
- // Boilerplate already exists and constant elements are never accessed,
- // pass an empty fixed array to the runtime function instead.
- Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
+ Handle<FixedArray> constants = expr->constant_elements();
int literal_index = expr->literal_index();
int flags = expr->ComputeFlags(true);
@@ -6058,7 +6203,9 @@
literal = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 4);
// Register to deopt if the boilerplate ElementsKind changes.
- top_info()->dependencies()->AssumeTransitionStable(site);
+ if (!site.is_null()) {
+ top_info()->dependencies()->AssumeTransitionStable(site);
+ }
}
// The array is expected in the bailout environment during computation
@@ -6083,21 +6230,28 @@
HValue* key = Add<HConstant>(i);
- switch (boilerplate_elements_kind) {
- case FAST_SMI_ELEMENTS:
- case FAST_HOLEY_SMI_ELEMENTS:
- case FAST_ELEMENTS:
- case FAST_HOLEY_ELEMENTS:
- case FAST_DOUBLE_ELEMENTS:
- case FAST_HOLEY_DOUBLE_ELEMENTS: {
- HStoreKeyed* instr = Add<HStoreKeyed>(elements, key, value, nullptr,
- boilerplate_elements_kind);
- instr->SetUninitialized(uninitialized);
- break;
+ if (!boilerplate_object.is_null()) {
+ ElementsKind boilerplate_elements_kind =
+ boilerplate_object->GetElementsKind();
+ switch (boilerplate_elements_kind) {
+ case FAST_SMI_ELEMENTS:
+ case FAST_HOLEY_SMI_ELEMENTS:
+ case FAST_ELEMENTS:
+ case FAST_HOLEY_ELEMENTS:
+ case FAST_DOUBLE_ELEMENTS:
+ case FAST_HOLEY_DOUBLE_ELEMENTS: {
+ Add<HStoreKeyed>(elements, key, value, nullptr,
+ boilerplate_elements_kind);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
}
- default:
- UNREACHABLE();
- break;
+ } else {
+ HInstruction* instr = BuildKeyedGeneric(
+ STORE, expr, expr->LiteralFeedbackSlot(), literal, key, value);
+ AddInstruction(instr);
}
Add<HSimulate>(expr->GetIdForElement(i));
@@ -6176,10 +6330,9 @@
HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
// TODO(hpayer): Allocation site pretenuring support.
- HInstruction* heap_number = Add<HAllocate>(heap_number_size,
- HType::HeapObject(),
- NOT_TENURED,
- MUTABLE_HEAP_NUMBER_TYPE);
+ HInstruction* heap_number =
+ Add<HAllocate>(heap_number_size, HType::HeapObject(), NOT_TENURED,
+ MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0());
AddStoreMapConstant(
heap_number, isolate()->factory()->mutable_heap_number_map());
Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
@@ -6761,7 +6914,6 @@
// possible if the receiver had a known map at some point, and no
// map-changing stores have happened to it since.
Handle<Map> candidate_map = receiver->GetMonomorphicJSObjectMap();
- if (candidate_map->is_observed()) return false;
for (HInstruction* current = builder->current_block()->last();
current != nullptr; current = current->previous()) {
if (current->IsBlockEntry()) break;
@@ -7026,7 +7178,11 @@
case CONST:
return Bailout(kNonInitializerAssignmentToConst);
case CONST_LEGACY:
- return ast_context()->ReturnValue(Pop());
+ if (is_strict(function_language_mode())) {
+ return Bailout(kNonInitializerAssignmentToConst);
+ } else {
+ return ast_context()->ReturnValue(Pop());
+ }
default:
mode = HStoreContextSlot::kNoCheck;
}
@@ -7095,10 +7251,16 @@
}
} else if (var->mode() == CONST_LEGACY) {
if (expr->op() != Token::INIT) {
- CHECK_ALIVE(VisitForValue(expr->value()));
- return ast_context()->ReturnValue(Pop());
+ if (is_strict(function_language_mode())) {
+ return Bailout(kNonInitializerAssignmentToConst);
+ } else {
+ CHECK_ALIVE(VisitForValue(expr->value()));
+ return ast_context()->ReturnValue(Pop());
+ }
}
+ // TODO(adamk): Is this required? Legacy const variables are always
+ // initialized before use.
if (var->IsStackAllocated()) {
// We insert a use of the old value to detect unsupported uses of const
// variables (e.g. initialization inside a loop).
@@ -7170,11 +7332,7 @@
}
} else {
DCHECK_EQ(Token::INIT, expr->op());
- if (var->mode() == CONST_LEGACY) {
- mode = HStoreContextSlot::kCheckIgnoreAssignment;
- } else {
- mode = HStoreContextSlot::kNoCheck;
- }
+ mode = HStoreContextSlot::kNoCheck;
}
HValue* context = BuildContextChainWalk(var);
@@ -7546,9 +7704,13 @@
// Get transition target for each map (NULL == no transition).
for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i);
- Handle<Map> transitioned_map =
- Map::FindTransitionedMap(map, &possible_transitioned_maps);
- transition_target.Add(transitioned_map);
+ Map* transitioned_map =
+ map->FindElementsKindTransitionedMap(&possible_transitioned_maps);
+ if (transitioned_map != nullptr) {
+ transition_target.Add(handle(transitioned_map));
+ } else {
+ transition_target.Add(Handle<Map>());
+ }
}
MapHandleList untransitionable_maps(maps->length());
@@ -8025,7 +8187,7 @@
HConstant* stub = Add<HConstant>(callable.code());
return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
- Vector<HValue*>(op_vals, arraysize(op_vals)),
+ ArrayVector(op_vals),
syntactic_tail_call_mode);
}
@@ -8050,7 +8212,7 @@
HConstant* stub = Add<HConstant>(callable.code());
return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
- Vector<HValue*>(op_vals, arraysize(op_vals)),
+ ArrayVector(op_vals),
syntactic_tail_call_mode);
}
@@ -8402,7 +8564,7 @@
top_info()->parse_info()->ast_value_factory());
parse_info.set_ast_value_factory_owned(false);
- CompilationInfo target_info(&parse_info);
+ CompilationInfo target_info(&parse_info, target);
Handle<SharedFunctionInfo> target_shared(target->shared());
if (inlining_kind != CONSTRUCT_CALL_RETURN &&
@@ -8424,6 +8586,10 @@
TraceInline(target, caller, "parse failure");
return false;
}
+ if (target_shared->dont_crankshaft()) {
+ TraceInline(target, caller, "ParseAndAnalyze found incompatibility");
+ return false;
+ }
if (target_info.scope()->num_heap_slots() > 0) {
TraceInline(target, caller, "target has context-allocated variables");
@@ -8496,13 +8662,13 @@
// Type-check the inlined function.
DCHECK(target_shared->has_deoptimization_support());
AstTyper(target_info.isolate(), target_info.zone(), target_info.closure(),
- target_info.scope(), target_info.osr_ast_id(), target_info.literal())
+ target_info.scope(), target_info.osr_ast_id(), target_info.literal(),
+ &bounds_)
.Run();
int inlining_id = 0;
if (top_info()->is_tracking_positions()) {
- inlining_id = top_info()->TraceInlinedFunction(
- target_shared, source_position(), function_state()->inlining_id());
+ inlining_id = TraceInlinedFunction(target_shared, source_position());
}
// Save the pending call context. Set up new one for the inlined function.
@@ -8767,8 +8933,7 @@
return !receiver_map.is_null() && receiver_map->prototype()->IsJSObject() &&
receiver_map->instance_type() == JS_ARRAY_TYPE &&
IsFastElementsKind(receiver_map->elements_kind()) &&
- !receiver_map->is_dictionary_map() && !receiver_map->is_observed() &&
- receiver_map->is_extensible() &&
+ !receiver_map->is_dictionary_map() && receiver_map->is_extensible() &&
(!receiver_map->is_prototype_map() || receiver_map->is_stable()) &&
!IsReadOnlyLengthDescriptor(receiver_map);
}
@@ -9145,7 +9310,6 @@
if (!receiver_map->prototype()->IsJSObject()) return false;
ElementsKind kind = receiver_map->elements_kind();
if (!IsFastElementsKind(kind)) return false;
- if (receiver_map->is_observed()) return false;
if (argument_count != 2) return false;
if (!receiver_map->is_extensible()) return false;
@@ -10091,9 +10255,8 @@
Callable callable = CodeFactory::Construct(isolate());
HConstant* stub = Add<HConstant>(callable.code());
PushArgumentsFromEnvironment(argument_count);
- HInstruction* construct =
- New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
- Vector<HValue*>(op_vals, arraysize(op_vals)));
+ HInstruction* construct = New<HCallWithDescriptor>(
+ stub, argument_count, callable.descriptor(), ArrayVector(op_vals));
return ast_context()->ReturnInstruction(construct, expr->id());
}
@@ -10202,7 +10365,8 @@
length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
HValue* elements = Add<HAllocate>(
Add<HConstant>(FixedTypedArrayBase::kHeaderSize), HType::HeapObject(),
- NOT_TENURED, external_array_map->instance_type());
+ NOT_TENURED, external_array_map->instance_type(),
+ graph()->GetConstant0());
AddStoreMapConstant(elements, external_array_map);
Add<HStoreNamedField>(elements,
@@ -10258,9 +10422,9 @@
length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
Handle<Map> fixed_typed_array_map(
isolate()->heap()->MapForFixedTypedArray(array_type));
- HAllocate* elements =
- Add<HAllocate>(total_size, HType::HeapObject(), NOT_TENURED,
- fixed_typed_array_map->instance_type());
+ HAllocate* elements = Add<HAllocate>(
+ total_size, HType::HeapObject(), NOT_TENURED,
+ fixed_typed_array_map->instance_type(), graph()->GetConstant0());
#ifndef V8_HOST_ARCH_64_BIT
if (array_type == kExternalFloat64Array) {
@@ -10972,9 +11136,9 @@
HValue* left,
HValue* right,
PushBeforeSimulateBehavior push_sim_result) {
- Type* left_type = expr->left()->bounds().lower;
- Type* right_type = expr->right()->bounds().lower;
- Type* result_type = expr->bounds().lower;
+ Type* left_type = bounds_.get(expr->left()).lower;
+ Type* right_type = bounds_.get(expr->right()).lower;
+ Type* result_type = bounds_.get(expr).lower;
Maybe<int> fixed_right_arg = expr->fixed_right_arg();
Handle<AllocationSite> allocation_site = expr->allocation_site();
@@ -11159,46 +11323,53 @@
// inline several instructions (including the two pushes) for every tagged
// operation in optimized code, which is more expensive, than a stub call.
if (graph()->info()->IsStub() && is_non_primitive) {
- Runtime::FunctionId function_id;
+ HValue* values[] = {context(), left, right};
+#define GET_STUB(Name) \
+ do { \
+ Callable callable = CodeFactory::Name(isolate()); \
+ HValue* stub = Add<HConstant>(callable.code()); \
+ instr = AddUncasted<HCallWithDescriptor>(stub, 0, callable.descriptor(), \
+ ArrayVector(values)); \
+ } while (false)
+
switch (op) {
default:
UNREACHABLE();
case Token::ADD:
- function_id = Runtime::kAdd;
+ GET_STUB(Add);
break;
case Token::SUB:
- function_id = Runtime::kSubtract;
+ GET_STUB(Subtract);
break;
case Token::MUL:
- function_id = Runtime::kMultiply;
+ GET_STUB(Multiply);
break;
case Token::DIV:
- function_id = Runtime::kDivide;
+ GET_STUB(Divide);
break;
case Token::MOD:
- function_id = Runtime::kModulus;
+ GET_STUB(Modulus);
break;
case Token::BIT_OR:
- function_id = Runtime::kBitwiseOr;
+ GET_STUB(BitwiseOr);
break;
case Token::BIT_AND:
- function_id = Runtime::kBitwiseAnd;
+ GET_STUB(BitwiseAnd);
break;
case Token::BIT_XOR:
- function_id = Runtime::kBitwiseXor;
+ GET_STUB(BitwiseXor);
break;
case Token::SAR:
- function_id = Runtime::kShiftRight;
+ GET_STUB(ShiftRight);
break;
case Token::SHR:
- function_id = Runtime::kShiftRightLogical;
+ GET_STUB(ShiftRightLogical);
break;
case Token::SHL:
- function_id = Runtime::kShiftLeft;
+ GET_STUB(ShiftLeft);
break;
}
- Add<HPushArguments>(left, right);
- instr = AddUncasted<HCallRuntime>(Runtime::FunctionForId(function_id), 2);
+#undef GET_STUB
} else {
switch (op) {
case Token::ADD:
@@ -11502,8 +11673,8 @@
return ast_context()->ReturnControl(instr, expr->id());
}
- Type* left_type = expr->left()->bounds().lower;
- Type* right_type = expr->right()->bounds().lower;
+ Type* left_type = bounds_.get(expr->left()).lower;
+ Type* right_type = bounds_.get(expr->right()).lower;
Type* combined_type = expr->combined_type();
CHECK_ALIVE(VisitForValue(expr->left()));
@@ -11520,18 +11691,24 @@
}
if (op == Token::INSTANCEOF) {
- DCHECK(!FLAG_harmony_instanceof);
// Check to see if the rhs of the instanceof is a known function.
if (right->IsConstant() &&
HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
- Handle<JSFunction> constructor =
+ Handle<JSFunction> function =
Handle<JSFunction>::cast(HConstant::cast(right)->handle(isolate()));
- if (constructor->IsConstructor() &&
- !constructor->map()->has_non_instance_prototype()) {
- JSFunction::EnsureHasInitialMap(constructor);
- DCHECK(constructor->has_initial_map());
- Handle<Map> initial_map(constructor->initial_map(), isolate());
+ // Make sure the prototype of {function} is the %FunctionPrototype%, and
+ // it already has a meaningful initial map (i.e. we constructed at least
+ // one instance using the constructor {function}).
+ // We can only use the fast case if @@hasInstance was not used so far.
+ if (function->has_initial_map() &&
+ function->map()->prototype() ==
+ function->native_context()->closure() &&
+ !function->map()->has_non_instance_prototype() &&
+ isolate()->IsHasInstanceLookupChainIntact()) {
+ Handle<Map> initial_map(function->initial_map(), isolate());
top_info()->dependencies()->AssumeInitialMapCantChange(initial_map);
+ top_info()->dependencies()->AssumePropertyCell(
+ isolate()->factory()->has_instance_protector());
HInstruction* prototype =
Add<HConstant>(handle(initial_map->prototype(), isolate()));
HHasInPrototypeChainAndBranch* result =
@@ -11540,13 +11717,21 @@
}
}
- HInstanceOf* result = New<HInstanceOf>(left, right);
+ Callable callable = CodeFactory::InstanceOf(isolate());
+ HValue* stub = Add<HConstant>(callable.code());
+ HValue* values[] = {context(), left, right};
+ HCallWithDescriptor* result = New<HCallWithDescriptor>(
+ stub, 0, callable.descriptor(), ArrayVector(values));
+ result->set_type(HType::Boolean());
return ast_context()->ReturnInstruction(result, expr->id());
} else if (op == Token::IN) {
- Add<HPushArguments>(left, right);
+ Callable callable = CodeFactory::HasProperty(isolate());
+ HValue* stub = Add<HConstant>(callable.code());
+ HValue* values[] = {context(), left, right};
HInstruction* result =
- New<HCallRuntime>(Runtime::FunctionForId(Runtime::kHasProperty), 2);
+ New<HCallWithDescriptor>(stub, 0, callable.descriptor(),
+ Vector<HValue*>(values, arraysize(values)));
return ast_context()->ReturnInstruction(result, expr->id());
}
@@ -11827,8 +12012,9 @@
}
top_info()->dependencies()->AssumeTransitionStable(current_site);
- HInstruction* object = Add<HAllocate>(
- object_size_constant, type, pretenure_flag, instance_type, top_site);
+ HInstruction* object =
+ Add<HAllocate>(object_size_constant, type, pretenure_flag, instance_type,
+ graph()->GetConstant0(), top_site);
// If allocation folding reaches Page::kMaxRegularHeapObjectSize the
// elements array may not get folded into the object. Hence, we set the
@@ -11869,7 +12055,8 @@
InstanceType instance_type = boilerplate_object->HasFastDoubleElements()
? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE;
object_elements = Add<HAllocate>(object_elements_size, HType::HeapObject(),
- pretenure_flag, instance_type, top_site);
+ pretenure_flag, instance_type,
+ graph()->GetConstant0(), top_site);
BuildEmitElements(boilerplate_object, elements, object_elements,
site_context);
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
@@ -11970,9 +12157,9 @@
if (representation.IsDouble()) {
// Allocate a HeapNumber box and store the value into it.
HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
- HInstruction* double_box =
- Add<HAllocate>(heap_number_constant, HType::HeapObject(),
- pretenure_flag, MUTABLE_HEAP_NUMBER_TYPE);
+ HInstruction* double_box = Add<HAllocate>(
+ heap_number_constant, HType::HeapObject(), pretenure_flag,
+ MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0());
AddStoreMapConstant(double_box,
isolate()->factory()->mutable_heap_number_map());
// Unwrap the mutable heap number from the boilerplate.
@@ -12113,10 +12300,7 @@
Handle<FixedArray> array =
isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
- int flags =
- DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
- DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
- DeclareGlobalsLanguageMode::encode(current_info()->language_mode());
+ int flags = current_info()->GetDeclareGlobalsFlags();
Add<HDeclareGlobals>(array, flags);
globals_.Rewind(0);
}
@@ -12128,14 +12312,13 @@
VariableProxy* proxy = declaration->proxy();
VariableMode mode = declaration->mode();
Variable* variable = proxy->var();
- bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
+ bool hole_init = mode == LET || mode == CONST;
switch (variable->location()) {
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED:
+ DCHECK(!variable->binding_needs_init());
globals_.Add(variable->name(), zone());
- globals_.Add(variable->binding_needs_init()
- ? isolate()->factory()->the_hole_value()
- : isolate()->factory()->undefined_value(), zone());
+ globals_.Add(isolate()->factory()->undefined_value(), zone());
return;
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
@@ -12291,9 +12474,8 @@
Callable callable = CodeFactory::ToInteger(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context(), input};
- HInstruction* result =
- New<HCallWithDescriptor>(stub, 0, callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result = New<HCallWithDescriptor>(
+ stub, 0, callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
}
@@ -12315,9 +12497,8 @@
Callable callable = CodeFactory::ToName(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context(), input};
- HInstruction* result =
- New<HCallWithDescriptor>(stub, 0, callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result = New<HCallWithDescriptor>(
+ stub, 0, callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
}
@@ -12342,9 +12523,8 @@
Callable callable = CodeFactory::ToString(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context(), input};
- HInstruction* result =
- New<HCallWithDescriptor>(stub, 0, callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result = New<HCallWithDescriptor>(
+ stub, 0, callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
}
@@ -12357,9 +12537,8 @@
HValue* input = Pop();
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context(), input};
- HInstruction* result =
- New<HCallWithDescriptor>(stub, 0, callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result = New<HCallWithDescriptor>(
+ stub, 0, callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
@@ -12532,9 +12711,9 @@
Callable callable = CodeFactory::SubString(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context()};
- HInstruction* result = New<HCallWithDescriptor>(
- stub, call->arguments()->length(), callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result =
+ New<HCallWithDescriptor>(stub, call->arguments()->length(),
+ callable.descriptor(), ArrayVector(values));
result->set_type(HType::String());
return ast_context()->ReturnInstruction(result, call->id());
}
@@ -12547,8 +12726,8 @@
FastNewObjectDescriptor descriptor(isolate());
HValue* values[] = {context(), Pop(), Pop()};
HConstant* stub_value = Add<HConstant>(stub.GetCode());
- HInstruction* result = New<HCallWithDescriptor>(
- stub_value, 0, descriptor, Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result =
+ New<HCallWithDescriptor>(stub_value, 0, descriptor, ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
@@ -12560,9 +12739,9 @@
Callable callable = CodeFactory::RegExpExec(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context()};
- HInstruction* result = New<HCallWithDescriptor>(
- stub, call->arguments()->length(), callable.descriptor(),
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result =
+ New<HCallWithDescriptor>(stub, call->arguments()->length(),
+ callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
@@ -12644,54 +12823,15 @@
void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) {
DCHECK_LE(2, call->arguments()->length());
CHECK_ALIVE(VisitExpressions(call->arguments()));
-
- // Try and customize ES6 instanceof here.
- // We should at least have the constructor on the expression stack.
- if (FLAG_harmony_instanceof && FLAG_harmony_instanceof_opt &&
- call->arguments()->length() == 3) {
- HValue* target = environment()->ExpressionStackAt(2);
- if (target->IsConstant()) {
- HConstant* constant_function = HConstant::cast(target);
- if (constant_function->handle(isolate())->IsJSFunction()) {
- Handle<JSFunction> func =
- Handle<JSFunction>::cast(constant_function->handle(isolate()));
- if (*func == isolate()->native_context()->ordinary_has_instance()) {
- // Look at the function, which will be argument 1.
- HValue* right = environment()->ExpressionStackAt(1);
- if (right->IsConstant() &&
- HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
- Handle<JSFunction> constructor = Handle<JSFunction>::cast(
- HConstant::cast(right)->handle(isolate()));
- if (constructor->IsConstructor() &&
- !constructor->map()->has_non_instance_prototype()) {
- JSFunction::EnsureHasInitialMap(constructor);
- DCHECK(constructor->has_initial_map());
- Handle<Map> initial_map(constructor->initial_map(), isolate());
- top_info()->dependencies()->AssumeInitialMapCantChange(
- initial_map);
- HInstruction* prototype =
- Add<HConstant>(handle(initial_map->prototype(), isolate()));
- HValue* left = environment()->ExpressionStackAt(0);
- HHasInPrototypeChainAndBranch* result =
- New<HHasInPrototypeChainAndBranch>(left, prototype);
- Drop(3);
- return ast_context()->ReturnControl(result, call->id());
- }
- }
- }
- }
- }
- }
-
CallTrampolineDescriptor descriptor(isolate());
PushArgumentsFromEnvironment(call->arguments()->length() - 1);
HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call());
HValue* target = Pop();
HValue* values[] = {context(), target,
Add<HConstant>(call->arguments()->length() - 2)};
- HInstruction* result = New<HCallWithDescriptor>(
- trampoline, call->arguments()->length() - 1, descriptor,
- Vector<HValue*>(values, arraysize(values)));
+ HInstruction* result =
+ New<HCallWithDescriptor>(trampoline, call->arguments()->length() - 1,
+ descriptor, ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}
@@ -12793,7 +12933,7 @@
// Allocate the table and add the proper map.
HValue* table =
Add<HAllocate>(Add<HConstant>(kSizeInBytes), HType::HeapObject(),
- NOT_TENURED, FIXED_ARRAY_TYPE);
+ NOT_TENURED, FIXED_ARRAY_TYPE, graph()->GetConstant0());
AddStoreMapConstant(table, isolate()->factory()->ordered_hash_table_map());
// Initialize the FixedArray...
@@ -12923,13 +13063,6 @@
return ast_context()->ReturnValue(value);
}
-void HOptimizedGraphBuilder::GenerateGetOrdinaryHasInstance(CallRuntime* call) {
- DCHECK(call->arguments()->length() == 0);
- // ordinary_has_instance is immutable so we can treat it as a constant.
- HValue* value = Add<HConstant>(isolate()->ordinary_has_instance());
- return ast_context()->ReturnValue(value);
-}
-
#undef CHECK_BAILOUT
#undef CHECK_ALIVE
@@ -13251,13 +13384,24 @@
void HTracer::TraceCompilation(CompilationInfo* info) {
Tag tag(this, "compilation");
- base::SmartArrayPointer<char> name = info->GetDebugName();
+ std::string name;
+ Object* source_name = info->script()->name();
+ if (source_name->IsString()) {
+ String* str = String::cast(source_name);
+ if (str->length() > 0) {
+ name.append(str->ToCString().get());
+ name.append(":");
+ }
+ }
+ base::SmartArrayPointer<char> method_name = info->GetDebugName();
+ name.append(method_name.get());
if (info->IsOptimizing()) {
- PrintStringProperty("name", name.get());
+ PrintStringProperty("name", name.c_str());
PrintIndent();
- trace_.Add("method \"%s:%d\"\n", name.get(), info->optimization_id());
+ trace_.Add("method \"%s:%d\"\n", method_name.get(),
+ info->optimization_id());
} else {
- PrintStringProperty("name", name.get());
+ PrintStringProperty("name", name.c_str());
PrintStringProperty("method", "stub");
}
PrintLongProperty("date",