1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef jit_BytecodeAnalysis_h
8 #define jit_BytecodeAnalysis_h
9 
10 #include "jit/JitAllocPolicy.h"
11 #include "js/Vector.h"
12 #include "vm/JSScript.h"
13 
14 namespace js {
15 namespace jit {
16 
17 // Basic information about bytecodes in the script.  Used to help baseline
18 // compilation.
19 struct BytecodeInfo {
20   static const uint16_t MAX_STACK_DEPTH = 0xffffU;
21   uint16_t stackDepth;
22   bool initialized : 1;
23   bool jumpTarget : 1;
24 
25   // If true, this is a JSOp::LoopHead where we can OSR into Ion/Warp code.
26   bool loopHeadCanOsr : 1;
27 
28   // See the comment above normallyReachable in BytecodeAnalysis.cpp for how
29   // this works.
30   bool jumpTargetNormallyReachable : 1;
31 
32   // True if the script has a resume offset for this bytecode op.
33   bool hasResumeOffset : 1;
34 
initBytecodeInfo35   void init(unsigned depth) {
36     MOZ_ASSERT(depth <= MAX_STACK_DEPTH);
37     MOZ_ASSERT_IF(initialized, stackDepth == depth);
38     initialized = true;
39     stackDepth = depth;
40   }
41 
setJumpTargetBytecodeInfo42   void setJumpTarget(bool normallyReachable) {
43     jumpTarget = true;
44     if (normallyReachable) {
45       jumpTargetNormallyReachable = true;
46     }
47   }
48 };
49 
50 class BytecodeAnalysis {
51   JSScript* script_;
52   Vector<BytecodeInfo, 0, JitAllocPolicy> infos_;
53 
54  public:
55   explicit BytecodeAnalysis(TempAllocator& alloc, JSScript* script);
56 
57   [[nodiscard]] bool init(TempAllocator& alloc);
58 
info(jsbytecode * pc)59   BytecodeInfo& info(jsbytecode* pc) {
60     uint32_t pcOffset = script_->pcToOffset(pc);
61     MOZ_ASSERT(infos_[pcOffset].initialized);
62     return infos_[pcOffset];
63   }
64 
maybeInfo(jsbytecode * pc)65   BytecodeInfo* maybeInfo(jsbytecode* pc) {
66     uint32_t pcOffset = script_->pcToOffset(pc);
67     if (infos_[pcOffset].initialized) {
68       return &infos_[pcOffset];
69     }
70     return nullptr;
71   }
72 
73   void checkWarpSupport(JSOp op);
74 };
75 
76 // Bytecode analysis pass necessary for WarpBuilder. The result is cached in
77 // JitScript.
78 struct IonBytecodeInfo;
79 IonBytecodeInfo AnalyzeBytecodeForIon(JSContext* cx, JSScript* script);
80 
81 }  // namespace jit
82 }  // namespace js
83 
84 #endif /* jit_BytecodeAnalysis_h */
85