| // 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 "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<v8::Value>& args) { |
| JavaScriptFrameIterator it(CcTest::i_isolate()); |
| JavaScriptFrame* frame = it.frame(); |
| return args.GetReturnValue().Set(frame->is_optimized()); |
| } |
| |
| |
| static void InstallIsOptimizedHelper(v8::Isolate* isolate) { |
| v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| v8::Local<v8::FunctionTemplate> 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 |