1// Copyright 2018 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/codegen/code-reference.h"
6
7#include "src/codegen/code-desc.h"
8#include "src/common/globals.h"
9#include "src/handles/handles-inl.h"
10#include "src/objects/objects-inl.h"
11
12#if V8_ENABLE_WEBASSEMBLY
13#include "src/wasm/wasm-code-manager.h"
14#endif  // V8_ENABLE_WEBASSEMBLY
15
16namespace v8 {
17namespace internal {
18
19namespace {
20struct JSOps {
21  Handle<Code> code;
22
23  Address constant_pool() const { return code->constant_pool(); }
24  Address instruction_start() const { return code->InstructionStart(); }
25  Address instruction_end() const { return code->InstructionEnd(); }
26  int instruction_size() const { return code->InstructionSize(); }
27  const byte* relocation_start() const { return code->relocation_start(); }
28  const byte* relocation_end() const { return code->relocation_end(); }
29  int relocation_size() const { return code->relocation_size(); }
30  Address code_comments() const { return code->code_comments(); }
31  int code_comments_size() const { return code->code_comments_size(); }
32};
33
34#if V8_ENABLE_WEBASSEMBLY
35struct WasmOps {
36  const wasm::WasmCode* code;
37
38  Address constant_pool() const { return code->constant_pool(); }
39  Address instruction_start() const {
40    return reinterpret_cast<Address>(code->instructions().begin());
41  }
42  Address instruction_end() const {
43    return reinterpret_cast<Address>(code->instructions().begin() +
44                                     code->instructions().size());
45  }
46  int instruction_size() const { return code->instructions().length(); }
47  const byte* relocation_start() const { return code->reloc_info().begin(); }
48  const byte* relocation_end() const {
49    return code->reloc_info().begin() + code->reloc_info().length();
50  }
51  int relocation_size() const { return code->reloc_info().length(); }
52  Address code_comments() const { return code->code_comments(); }
53  int code_comments_size() const { return code->code_comments_size(); }
54};
55#endif  // V8_ENABLE_WEBASSEMBLY
56
57struct CodeDescOps {
58  const CodeDesc* code_desc;
59
60  Address constant_pool() const {
61    return instruction_start() + code_desc->constant_pool_offset;
62  }
63  Address instruction_start() const {
64    return reinterpret_cast<Address>(code_desc->buffer);
65  }
66  Address instruction_end() const {
67    return instruction_start() + code_desc->instr_size;
68  }
69  int instruction_size() const { return code_desc->instr_size; }
70  const byte* relocation_start() const {
71    return code_desc->buffer + code_desc->reloc_offset;
72  }
73  const byte* relocation_end() const {
74    return code_desc->buffer + code_desc->buffer_size;
75  }
76  int relocation_size() const { return code_desc->reloc_size; }
77  Address code_comments() const {
78    return instruction_start() + code_desc->code_comments_offset;
79  }
80  int code_comments_size() const { return code_desc->code_comments_size; }
81};
82}  // namespace
83
84#if V8_ENABLE_WEBASSEMBLY
85#define DISPATCH(ret, method)                    \
86  ret CodeReference::method() const {            \
87    DCHECK(!is_null());                          \
88    switch (kind_) {                             \
89      case Kind::JS:                             \
90        return JSOps{js_code_}.method();         \
91      case Kind::WASM:                           \
92        return WasmOps{wasm_code_}.method();     \
93      case Kind::CODE_DESC:                      \
94        return CodeDescOps{code_desc_}.method(); \
95      default:                                   \
96        UNREACHABLE();                           \
97    }                                            \
98  }
99#else
100#define DISPATCH(ret, method)                              \
101  ret CodeReference::method() const {                      \
102    DCHECK(!is_null());                                    \
103    DCHECK(kind_ == Kind::JS || kind_ == Kind::CODE_DESC); \
104    if (kind_ == Kind::JS) {                               \
105      return JSOps{js_code_}.method();                     \
106    } else {                                               \
107      return CodeDescOps{code_desc_}.method();             \
108    }                                                      \
109  }
110#endif  // V8_ENABLE_WEBASSEMBLY
111
112DISPATCH(Address, constant_pool)
113DISPATCH(Address, instruction_start)
114DISPATCH(Address, instruction_end)
115DISPATCH(int, instruction_size)
116DISPATCH(const byte*, relocation_start)
117DISPATCH(const byte*, relocation_end)
118DISPATCH(int, relocation_size)
119DISPATCH(Address, code_comments)
120DISPATCH(int, code_comments_size)
121
122#undef DISPATCH
123
124}  // namespace internal
125}  // namespace v8
126