// Copyright 2014 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 "include/v8-function.h" #include "src/execution/frames-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/function-tester.h" namespace v8 { namespace internal { namespace compiler { static void IsOptimized(const v8::FunctionCallbackInfo& args) { JavaScriptFrameIterator it(CcTest::i_isolate()); JavaScriptFrame* frame = it.frame(); return args.GetReturnValue().Set(frame->is_turbofan()); } static void InstallIsOptimizedHelper(v8::Isolate* isolate) { v8::Local context = isolate->GetCurrentContext(); v8::Local t = v8::FunctionTemplate::New(isolate, IsOptimized); CHECK(context->Global() ->Set(context, v8_str("IsOptimized"), t->GetFunction(context).ToLocalChecked()) .FromJust()); } TEST(DeoptSimple) { FLAG_allow_natives_syntax = true; FunctionTester T( "(function f(a) {" " var b = 1;" " if (!IsOptimized()) return 0;" " %DeoptimizeFunction(f);" " if (IsOptimized()) return 0;" " return a + b;" "})"); InstallIsOptimizedHelper(CcTest::isolate()); T.CheckCall(T.Val(2), T.Val(1)); } TEST(DeoptSimpleInExpr) { FLAG_allow_natives_syntax = true; FunctionTester T( "(function f(a) {" " var b = 1;" " var c = 2;" " if (!IsOptimized()) return 0;" " var d = b + (%DeoptimizeFunction(f), c);" " if (IsOptimized()) return 0;" " return d + a;" "})"); InstallIsOptimizedHelper(CcTest::isolate()); T.CheckCall(T.Val(6), T.Val(3)); } TEST(DeoptExceptionHandlerCatch) { FLAG_allow_natives_syntax = true; FunctionTester T( "(function f() {" " var is_opt = IsOptimized;" " try {" " DeoptAndThrow(f);" " } catch (e) {" " return is_opt();" " }" "})"); CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }"); InstallIsOptimizedHelper(CcTest::isolate()); T.CheckCall(T.false_value()); } TEST(DeoptExceptionHandlerFinally) { FLAG_allow_natives_syntax = true; FunctionTester T( "(function f() {" " var is_opt = IsOptimized;" " try {" " DeoptAndThrow(f);" " } finally {" " return is_opt();" " }" "})"); CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }"); InstallIsOptimizedHelper(CcTest::isolate()); T.CheckCall(T.false_value()); } TEST(DeoptTrivial) { FLAG_allow_natives_syntax = true; FunctionTester T( "(function foo() {" " %DeoptimizeFunction(foo);" " return 1;" "})"); T.CheckCall(T.Val(1)); } } // namespace compiler } // namespace internal } // namespace v8