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

Unified Diff: src/hydrogen.cc

Issue 330303002: Add machinery to support arguments escaping to safe builtins (Closed) Base URL: https://github.com/v8/v8.git@master
Patch Set: Created 6 years, 6 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/objects.h » ('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 658cc5c2f92edeaf2fb44dc30bc3ec3aa2edd30c..a26d4d126383da97a64b7e05794ab7a9b293c01d 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4173,6 +4173,33 @@ void HOptimizedGraphBuilder::VisitExpressions(
}
+void HOptimizedGraphBuilder::VisitCallArguments(ZoneList<Expression*>* args,
+ HValue* function,
+ bool* args_contain_arguments) {
+ Handle<JSFunction> known_function;
+ ArgumentsAllowedFlag is_arguments_allowed = ARGUMENTS_NOT_ALLOWED;
+ if (function->IsConstant() &&
+ HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
+ known_function = Handle<JSFunction>::cast(
+ HConstant::cast(function)->handle(isolate()));
+
+ if (known_function->shared()->CanHandleArgumentsSafely()) {
+ ASSERT(known_function->shared()->HasBuiltinFunctionId());
+ is_arguments_allowed = ARGUMENTS_ALLOWED;
+ }
+ }
+
+ bool found_arguments = false;
+ for (int i = 0; i < args->length(); i++) {
+ CHECK_ALIVE(VisitForValue(args->at(i), is_arguments_allowed));
+ if (!found_arguments)
+ found_arguments = Top()->CheckFlag(HValue::kIsArguments);
+ }
+ *args_contain_arguments = found_arguments;
+ if (found_arguments) ASSERT(is_arguments_allowed == ARGUMENTS_ALLOWED);
+}
+
+
bool HOptimizedGraphBuilder::BuildGraph() {
if (current_info()->function()->is_generator()) {
Bailout(kFunctionIsAGenerator);
@@ -8367,6 +8394,30 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
}
+void HOptimizedGraphBuilder::InlineBuiltinWithArguments(
+ Call* expr,
+ HValue* function,
+ Handle<Map> receiver_map,
+ int args_count_no_receiver) {
+ ASSERT(function->IsConstant() &&
+ HConstant::cast(function)->handle(isolate())->IsJSFunction());
+ Handle<JSFunction> known_function = Handle<JSFunction>::cast(
+ HConstant::cast(function)->handle(isolate()));
+ ASSERT(known_function->shared()->CanHandleArgumentsSafely());
+ ASSERT(known_function->shared()->HasBuiltinFunctionId());
+ if (TryInlineBuiltinMethodCall(expr, known_function, receiver_map,
+ args_count_no_receiver)) {
+ if (FLAG_trace_inlining) {
+ PrintF("Inlining builtin ");
+ known_function->ShortPrint();
+ PrintF("\n");
+ }
+ } else {
+ Bailout(kBadValueContextForArgumentsValue);
+ }
+}
+
+
bool HOptimizedGraphBuilder::TryInlineApiFunctionCall(Call* expr,
HValue* receiver) {
Handle<JSFunction> function = expr->target();
@@ -8660,20 +8711,25 @@ void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) {
int args_length = args->length();
Drop(1); // call
+ Push(function);
+ bool have_arguments = false;
if (args_length == 0) {
- receiver = graph()->GetConstantUndefined();
+ receiver = BuildWrapReceiver(graph()->GetConstantUndefined(), function);
args_length = 1;
+ Push(receiver);
} else {
- CHECK_ALIVE(VisitForValue(args->at(0)));
- receiver = Pop();
+ CHECK_ALIVE(VisitCallArguments(args, function, &have_arguments));
+ receiver = BuildWrapReceiver(
+ environment()->ExpressionStackAt(args_length - 1), function);
+ environment()->SetExpressionStackAt(args_length - 1, receiver);
}
- receiver = BuildWrapReceiver(receiver, function);
- Push(function);
- Push(receiver);
- for (int i = 1; i < args_length; i++) {
- CHECK_ALIVE(VisitForValue(args->at(i)));
+ if (have_arguments) {
+ Handle<Map> map;
+ CHECK_BAILOUT(InlineBuiltinWithArguments(expr, function, map,
+ args_length - 1));
}
+ ASSERT(!have_arguments);
HandleIndirectCall(expr, function, args_length);
}
@@ -8940,9 +8996,18 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
expr->set_target(known_function);
if (TryIndirectCall(expr)) return;
- CHECK_ALIVE(VisitExpressions(expr->arguments()));
+ bool have_arguments = false;
+ CHECK_ALIVE(VisitCallArguments(expr->arguments(), function,
+ &have_arguments));
Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>();
+ if (have_arguments) {
+ CHECK_BAILOUT(InlineBuiltinWithArguments(expr,
+ function,
+ map,
+ expr->arguments()->length()));
+ }
+ ASSERT(!have_arguments);
if (TryInlineBuiltinMethodCall(expr, known_function, map,
expr->arguments()->length())) {
if (FLAG_trace_inlining) {
« no previous file with comments | « src/hydrogen.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698