1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/frames-inl.h"
6#include "test/cctest/cctest.h"
7#include "test/cctest/compiler/function-tester.h"
8
9namespace v8 {
10namespace internal {
11namespace compiler {
12
13static void IsOptimized(const v8::FunctionCallbackInfo<v8::Value>& args) {
14  JavaScriptFrameIterator it(CcTest::i_isolate());
15  JavaScriptFrame* frame = it.frame();
16  return args.GetReturnValue().Set(frame->is_optimized());
17}
18
19
20static void InstallIsOptimizedHelper(v8::Isolate* isolate) {
21  v8::Local<v8::Context> context = isolate->GetCurrentContext();
22  v8::Local<v8::FunctionTemplate> t =
23      v8::FunctionTemplate::New(isolate, IsOptimized);
24  CHECK(context->Global()
25            ->Set(context, v8_str("IsOptimized"),
26                  t->GetFunction(context).ToLocalChecked())
27            .FromJust());
28}
29
30
31TEST(DeoptSimple) {
32  FLAG_allow_natives_syntax = true;
33
34  FunctionTester T(
35      "(function f(a) {"
36      "  var b = 1;"
37      "  if (!IsOptimized()) return 0;"
38      "  %DeoptimizeFunction(f);"
39      "  if (IsOptimized()) return 0;"
40      "  return a + b;"
41      "})");
42
43  InstallIsOptimizedHelper(CcTest::isolate());
44  T.CheckCall(T.Val(2), T.Val(1));
45}
46
47
48TEST(DeoptSimpleInExpr) {
49  FLAG_allow_natives_syntax = true;
50
51  FunctionTester T(
52      "(function f(a) {"
53      "  var b = 1;"
54      "  var c = 2;"
55      "  if (!IsOptimized()) return 0;"
56      "  var d = b + (%DeoptimizeFunction(f), c);"
57      "  if (IsOptimized()) return 0;"
58      "  return d + a;"
59      "})");
60
61  InstallIsOptimizedHelper(CcTest::isolate());
62  T.CheckCall(T.Val(6), T.Val(3));
63}
64
65
66TEST(DeoptExceptionHandlerCatch) {
67  FLAG_allow_natives_syntax = true;
68
69  FunctionTester T(
70      "(function f() {"
71      "  var is_opt = IsOptimized;"
72      "  try {"
73      "    DeoptAndThrow(f);"
74      "  } catch (e) {"
75      "    return is_opt();"
76      "  }"
77      "})");
78
79  CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
80  InstallIsOptimizedHelper(CcTest::isolate());
81  T.CheckCall(T.false_value());
82}
83
84
85TEST(DeoptExceptionHandlerFinally) {
86  FLAG_allow_natives_syntax = true;
87  FLAG_turbo_try_finally = true;
88
89  FunctionTester T(
90      "(function f() {"
91      "  var is_opt = IsOptimized;"
92      "  try {"
93      "    DeoptAndThrow(f);"
94      "  } finally {"
95      "    return is_opt();"
96      "  }"
97      "})");
98
99  CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
100  InstallIsOptimizedHelper(CcTest::isolate());
101#if 0  // TODO(4195,mstarzinger): Reproduces on MIPS64, re-enable once fixed.
102  T.CheckCall(T.false_value());
103#endif
104}
105
106
107TEST(DeoptTrivial) {
108  FLAG_allow_natives_syntax = true;
109
110  FunctionTester T(
111      "(function foo() {"
112      "  %DeoptimizeFunction(foo);"
113      "  return 1;"
114      "})");
115
116  T.CheckCall(T.Val(1));
117}
118
119}  // namespace compiler
120}  // namespace internal
121}  // namespace v8
122