v8/test/cctest/compiler/test-calls-with-arraylike-or-spread.cc
Dan Elphick 44fe02ced6 Revert "[include] Split out v8.h"
This reverts commit d1b27019d3.

Reason for revert: Broke vtune build, tsan build and possibly others

Original change's description:
> [include] Split out v8.h
>
> This moves every single class/function out of include/v8.h into a
> separate header in include/, which v8.h then includes so that
> externally nothing appears to have changed.
>
> Every include of v8.h from inside v8 has been changed to a more
> fine-grained include.
>
> Previously inline functions defined at the bottom of v8.h would call
> private non-inline functions in the V8 class. Since that class is now
> in v8-initialization.h and is rarely included (as that would create
> dependency cycles), this is not possible and so those methods have been
> moved out of the V8 class into the namespace v8::api_internal.
>
> None of the previous files in include/ now #include v8.h, which means
> if embedders were relying on this transitive dependency then it will
> give compile failures.
>
> v8-inspector.h does depend on v8-scripts.h for the time being to ensure
> that Chrome continue to compile but that change will be reverted once
> those transitive #includes in chrome are changed to include it directly.
>
> Full design:
> https://docs.google.com/document/d/1rTD--I8hCAr-Rho1WTumZzFKaDpEp0IJ8ejZtk4nJdA/edit?usp=sharing
>
> Bug: v8:11965
> Change-Id: I53b84b29581632710edc80eb11f819c2097a2877
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3097448
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Commit-Queue: Dan Elphick <delphick@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#76424}

Bug: v8:11965
Change-Id: Id57313ae992e720c8b19abc975cd69729e1344aa
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3113627
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Owners-Override: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76428}
2021-08-23 11:54:09 +00:00

183 lines
6.2 KiB
C++

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/flags/flags.h"
#include "test/cctest/compiler/node-observer-tester.h"
#include "test/cctest/test-api.h"
namespace v8 {
namespace internal {
namespace compiler {
void CompileRunWithNodeObserver(const std::string& js_code,
int32_t expected_result,
IrOpcode::Value initial_call_opcode,
IrOpcode::Value updated_call_opcode1,
IrOpcode::Value updated_call_opcode2) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
FLAG_allow_natives_syntax = true;
FLAG_turbo_optimize_apply = true;
// Note: Make sure to not capture stack locations (e.g. `this`) here since
// these lambdas are executed on another thread.
ModificationObserver apply_call_observer(
[initial_call_opcode](const Node* node) {
CHECK_EQ(initial_call_opcode, node->opcode());
},
[updated_call_opcode1, updated_call_opcode2](
const Node* node,
const ObservableNodeState& old_state) -> NodeObserver::Observation {
if (updated_call_opcode1 == node->opcode()) {
return NodeObserver::Observation::kContinue;
} else {
CHECK(updated_call_opcode2 == node->opcode());
return NodeObserver::Observation::kStop;
}
});
{
ObserveNodeScope scope(reinterpret_cast<i::Isolate*>(isolate),
&apply_call_observer);
v8::Local<v8::Value> result_value = CompileRun(js_code.c_str());
CHECK(result_value->IsNumber());
int32_t result =
ConvertJSValue<int32_t>::Get(result_value, env.local()).ToChecked();
CHECK_EQ(result, expected_result);
}
}
TEST(ReduceJSCallWithArrayLike) {
CompileRunWithNodeObserver(
"function sum_js3(a, b, c) { return a + b + c; }"
"function foo(x, y, z) {"
" return %ObserveNode(sum_js3.apply(null, [x, y, z]));"
"}"
"%PrepareFunctionForOptimization(sum_js3);"
"%PrepareFunctionForOptimization(foo);"
"foo(41, 42, 43);"
"%OptimizeFunctionOnNextCall(foo);"
"foo(41, 42, 43);",
126, IrOpcode::kJSCall,
IrOpcode::kJSCall, // not JSCallWithArrayLike
IrOpcode::kPhi); // JSCall => Phi when the call is inlined.
}
TEST(ReduceJSCallWithSpread) {
CompileRunWithNodeObserver(
"function sum_js3(a, b, c) { return a + b + c; }"
"function foo(x, y, z) {"
" const numbers = [x, y, z];"
" return %ObserveNode(sum_js3(...numbers));"
"}"
"%PrepareFunctionForOptimization(sum_js3);"
"%PrepareFunctionForOptimization(foo);"
"foo(41, 42, 43);"
"%OptimizeFunctionOnNextCall(foo);"
"foo(41, 42, 43)",
126, IrOpcode::kJSCallWithSpread,
IrOpcode::kJSCall, // not JSCallWithSpread
IrOpcode::kPhi);
}
TEST(ReduceJSCreateClosure) {
CompileRunWithNodeObserver(
"function foo_closure() {"
" return function(a, b, c) {"
" return a + b + c;"
" }"
"}"
"const _foo_closure = foo_closure();"
"%PrepareFunctionForOptimization(_foo_closure);"
"function foo(x, y, z) {"
" return %ObserveNode(foo_closure().apply(null, [x, y, z]));"
"}"
"%PrepareFunctionForOptimization(foo_closure);"
"%PrepareFunctionForOptimization(foo);"
"foo(41, 42, 43);"
"%OptimizeFunctionOnNextCall(foo_closure);"
"%OptimizeFunctionOnNextCall(foo);"
"foo(41, 42, 43)",
126, IrOpcode::kJSCall,
IrOpcode::kJSCall, // not JSCallWithArrayLike
IrOpcode::kPhi);
}
TEST(ReduceJSCreateBoundFunction) {
CompileRunWithNodeObserver(
"function sum_js3(a, b, c) {"
" return this.x + a + b + c;"
"}"
"function foo(x, y ,z) {"
" return %ObserveNode(sum_js3.bind({x : 42}).apply(null, [ x, y, z ]));"
"}"
"%PrepareFunctionForOptimization(sum_js3);"
"%PrepareFunctionForOptimization(foo);"
"foo(41, 42, 43);"
"%OptimizeFunctionOnNextCall(foo);"
"foo(41, 42, 43)",
168, IrOpcode::kJSCall,
IrOpcode::kJSCall, // not JSCallWithArrayLike
IrOpcode::kPhi);
}
static void SumF(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
int this_x = args.This()
->Get(context, v8_str("x"))
.ToLocalChecked()
->Int32Value(context)
.FromJust();
args.GetReturnValue().Set(v8_num(
args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust() +
args[1]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust() +
this_x));
}
TEST(ReduceCAPICallWithArrayLike) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
FLAG_allow_natives_syntax = true;
FLAG_turbo_optimize_apply = true;
Local<v8::FunctionTemplate> sum = v8::FunctionTemplate::New(isolate, SumF);
CHECK(env->Global()
->Set(env.local(), v8_str("sum"),
sum->GetFunction(env.local()).ToLocalChecked())
.FromJust());
Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
v8::Local<v8::String> class_name = v8_str("the_class_name");
fun->SetClassName(class_name);
Local<ObjectTemplate> templ1 = ObjectTemplate::New(isolate, fun);
templ1->Set(isolate, "x", v8_num(42));
templ1->Set(isolate, "foo", sum);
Local<v8::Object> instance1 =
templ1->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("p"), instance1).FromJust());
std::string js_code =
"function bar(a, b) { return sum.apply(p, [a, b]); }"
"%PrepareFunctionForOptimization(bar);"
"bar(20, 22);"
"%OptimizeFunctionOnNextCall(bar);"
"bar(20, 22);";
v8::Local<v8::Value> result_value = CompileRun(js_code.c_str());
CHECK(result_value->IsNumber());
int32_t result =
ConvertJSValue<int32_t>::Get(result_value, env.local()).ToChecked();
CHECK_EQ(result, 84);
}
} // namespace compiler
} // namespace internal
} // namespace v8