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

Unified Diff: src/hydrogen.cc

Issue 300693002: Revert "Customized support for feedback on calls to Array." and follow-up fixes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 8e0858dca7ea91be64f320d0f83392c592cbf8d9..6059a2a65317b2d9dfba4505ad2ca835e339523e 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2474,14 +2474,14 @@ void HGraphBuilder::BuildFillElementsWithHole(HValue* elements,
}
// Special loop unfolding case
- STATIC_ASSERT(JSArray::kPreallocatedArrayElements <=
- kElementLoopUnrollThreshold);
+ static const int kLoopUnfoldLimit = 8;
+ STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit);
int initial_capacity = -1;
if (from->IsInteger32Constant() && to->IsInteger32Constant()) {
int constant_from = from->GetInteger32Constant();
int constant_to = to->GetInteger32Constant();
- if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) {
+ if (constant_from == 0 && constant_to <= kLoopUnfoldLimit) {
initial_capacity = constant_to;
}
}
@@ -8234,56 +8234,6 @@ HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
}
-void HOptimizedGraphBuilder::BuildArrayCall(Expression* expression,
- int arguments_count,
- HValue* function,
- Handle<AllocationSite> site) {
- Add<HCheckValue>(function, array_function());
-
- if (IsCallArrayInlineable(arguments_count, site)) {
- BuildInlinedCallArray(expression, arguments_count, site);
- return;
- }
-
- HInstruction* call = PreProcessCall(New<HCallNewArray>(
- function, arguments_count + 1, site->GetElementsKind()));
- if (expression->IsCall()) {
- Drop(1);
- }
- ast_context()->ReturnInstruction(call, expression->id());
-}
-
-
-bool HOptimizedGraphBuilder::TryHandleArrayCall(Call* expr, HValue* function) {
- if (!array_function().is_identical_to(expr->target())) {
- return false;
- }
-
- Handle<AllocationSite> site = expr->allocation_site();
- if (site.is_null()) return false;
-
- BuildArrayCall(expr,
- expr->arguments()->length(),
- function,
- site);
- return true;
-}
-
-
-bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr,
- HValue* function) {
- if (!array_function().is_identical_to(expr->target())) {
- return false;
- }
-
- BuildArrayCall(expr,
- expr->arguments()->length(),
- function,
- expr->allocation_site());
- return true;
-}
-
-
void HOptimizedGraphBuilder::VisitCall(Call* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
@@ -8378,7 +8328,8 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
// evaluation of the arguments.
CHECK_ALIVE(VisitForValue(expr->expression()));
HValue* function = Top();
- if (expr->global_call()) {
+ bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
+ if (global_call) {
Variable* var = proxy->var();
bool known_global_function = false;
// If there is a global property cell for the name at compile time and
@@ -8412,7 +8363,6 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
return;
}
if (TryInlineApiFunctionCall(expr, receiver)) return;
- if (TryHandleArrayCall(expr, function)) return;
if (TryInlineCall(expr)) return;
PushArgumentsFromEnvironment(argument_count);
@@ -8462,21 +8412,20 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
}
-void HOptimizedGraphBuilder::BuildInlinedCallArray(
- Expression* expression,
- int argument_count,
- Handle<AllocationSite> site) {
- ASSERT(!site.is_null());
- ASSERT(argument_count >= 0 && argument_count <= 1);
+void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) {
NoObservableSideEffectsScope no_effects(this);
+ int argument_count = expr->arguments()->length();
// We should at least have the constructor on the expression stack.
HValue* constructor = environment()->ExpressionStackAt(argument_count);
+ ElementsKind kind = expr->elements_kind();
+ Handle<AllocationSite> site = expr->allocation_site();
+ ASSERT(!site.is_null());
+
// Register on the site for deoptimization if the transition feedback changes.
AllocationSite::AddDependentCompilationInfo(
site, AllocationSite::TRANSITIONS, top_info());
- ElementsKind kind = site->GetElementsKind();
HInstruction* site_instruction = Add<HConstant>(site);
// In the single constant argument case, we may have to adjust elements kind
@@ -8499,12 +8448,32 @@ void HOptimizedGraphBuilder::BuildInlinedCallArray(
site_instruction,
constructor,
DISABLE_ALLOCATION_SITES);
- HValue* new_object = argument_count == 0
- ? array_builder.AllocateEmptyArray()
- : BuildAllocateArrayFromLength(&array_builder, Top());
-
- int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1);
- Drop(args_to_drop);
+ HValue* new_object;
+ if (argument_count == 0) {
+ new_object = array_builder.AllocateEmptyArray();
+ } else if (argument_count == 1) {
+ HValue* argument = environment()->Top();
+ new_object = BuildAllocateArrayFromLength(&array_builder, argument);
+ } else {
+ HValue* length = Add<HConstant>(argument_count);
+ // Smi arrays need to initialize array elements with the hole because
+ // bailout could occur if the arguments don't fit in a smi.
+ //
+ // TODO(mvstanton): If all the arguments are constants in smi range, then
+ // we could set fill_with_hole to false and save a few instructions.
+ JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind)
+ ? JSArrayBuilder::FILL_WITH_HOLE
+ : JSArrayBuilder::DONT_FILL_WITH_HOLE;
+ new_object = array_builder.AllocateArray(length, length, fill_mode);
+ HValue* elements = array_builder.GetElementsLocation();
+ for (int i = 0; i < argument_count; i++) {
+ HValue* value = environment()->ExpressionStackAt(argument_count - i - 1);
+ HValue* constant_i = Add<HConstant>(i);
+ Add<HStoreKeyed>(elements, constant_i, value, kind);
+ }
+ }
+
+ Drop(argument_count + 1); // drop constructor and args.
ast_context()->ReturnValue(new_object);
}
@@ -8518,13 +8487,14 @@ static bool IsAllocationInlineable(Handle<JSFunction> constructor) {
}
-bool HOptimizedGraphBuilder::IsCallArrayInlineable(
- int argument_count,
- Handle<AllocationSite> site) {
+bool HOptimizedGraphBuilder::IsCallNewArrayInlineable(CallNew* expr) {
Handle<JSFunction> caller = current_info()->closure();
- Handle<JSFunction> target = array_function();
+ Handle<JSFunction> target(isolate()->native_context()->array_function(),
+ isolate());
+ int argument_count = expr->arguments()->length();
// We should have the function plus array arguments on the environment stack.
ASSERT(environment()->length() >= (argument_count + 1));
+ Handle<AllocationSite> site = expr->allocation_site();
ASSERT(!site.is_null());
bool inline_ok = false;
@@ -8534,24 +8504,22 @@ bool HOptimizedGraphBuilder::IsCallArrayInlineable(
HValue* argument = Top();
if (argument->IsConstant()) {
// Do not inline if the constant length argument is not a smi or
- // outside the valid range for unrolled loop initialization.
+ // outside the valid range for a fast array.
HConstant* constant_argument = HConstant::cast(argument);
if (constant_argument->HasSmiValue()) {
int value = constant_argument->Integer32Value();
- inline_ok = value >= 0 && value <= kElementLoopUnrollThreshold;
+ inline_ok = value >= 0 &&
+ value < JSObject::kInitialMaxFastElementArray;
if (!inline_ok) {
TraceInline(target, caller,
- "Constant length outside of valid inlining range.");
+ "Length outside of valid array range");
}
}
} else {
- TraceInline(target, caller,
- "Dont inline [new] Array(n) where n isn't constant.");
+ inline_ok = true;
}
- } else if (argument_count == 0) {
- inline_ok = true;
} else {
- TraceInline(target, caller, "Too many arguments to inline.");
+ inline_ok = true;
}
} else {
TraceInline(target, caller, "AllocationSite requested no inlining.");
@@ -8676,10 +8644,25 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
} else {
// The constructor function is both an operand to the instruction and an
// argument to the construct call.
- if (TryHandleArrayCallNew(expr, function)) return;
+ Handle<JSFunction> array_function(
+ isolate()->native_context()->array_function(), isolate());
+ bool use_call_new_array = expr->target().is_identical_to(array_function);
+ if (use_call_new_array && IsCallNewArrayInlineable(expr)) {
+ // Verify we are still calling the array function for our native context.
+ Add<HCheckValue>(function, array_function);
+ BuildInlinedCallNewArray(expr);
+ return;
+ }
- HInstruction* call =
- PreProcessCall(New<HCallNew>(function, argument_count));
+ HBinaryCall* call;
+ if (use_call_new_array) {
+ Add<HCheckValue>(function, array_function);
+ call = New<HCallNewArray>(function, argument_count,
+ expr->elements_kind());
+ } else {
+ call = New<HCallNew>(function, argument_count);
+ }
+ PreProcessCall(call);
return ast_context()->ReturnInstruction(call, expr->id());
}
}
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698