• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5type FrameType extends Smi constexpr 'StackFrame::Type';
6const STUB_FRAME: constexpr FrameType
7    generates 'StackFrame::STUB';
8const kFrameTypeCount:
9    constexpr int31 generates 'StackFrame::NUMBER_OF_TYPES';
10
11FromConstexpr<FrameType, constexpr FrameType>(t: constexpr FrameType):
12    FrameType {
13  // Note that althought FrameTypes sometimes masquerade as Smis (their
14  // LSB is a zero), they are not. For efficiency in storing them as a
15  // constant into a frame, they are simply the FrameType value shifted
16  // up by a single bit.
17  const i: constexpr uintptr = %RawConstexprCast<constexpr uintptr>(t)
18      << kSmiTagSize;
19  return %RawDownCast<FrameType>(BitcastWordToTaggedSigned(i));
20}
21Cast<FrameType>(o: Object): FrameType
22    labels CastError {
23  if (TaggedIsNotSmi(o)) goto CastError;
24  dcheck(
25      Convert<int32>(BitcastTaggedToWordForTagAndSmiBits(o)) <
26      Convert<int32>(kFrameTypeCount << kSmiTagSize));
27  return %RawDownCast<FrameType>(o);
28}
29
30type FrameBase extends RawPtr constexpr 'void*';
31type StandardFrame extends FrameBase constexpr 'void*';
32type StubFrame extends FrameBase constexpr 'void*';
33type FrameWithArguments = StandardFrame;
34type Frame = FrameWithArguments|StubFrame;
35
36extern macro LoadFramePointer(): Frame;
37extern macro LoadParentFramePointer(): Frame;
38
39// Load values from a specified frame by given offset in bytes.
40macro LoadObjectFromFrame(f: Frame, o: constexpr int32): Object {
41  return LoadBufferObject(f, o);
42}
43macro LoadPointerFromFrame(f: Frame, o: constexpr int32): RawPtr {
44  return LoadBufferPointer(f, o);
45}
46macro LoadIntptrFromFrame(f: Frame, o: constexpr int32): intptr {
47  return LoadBufferIntptr(f, o);
48}
49
50const kStandardFrameFunctionOffset: constexpr int31
51    generates 'StandardFrameConstants::kFunctionOffset';
52operator '.function' macro LoadFunctionFromFrame(f: Frame): JSFunction {
53  // TODO(danno): Use RawDownCast here in order to avoid passing the implicit
54  // context, since this accessor is used in legacy CSA code through
55  // LoadTargetFromFrame
56  const result: Object = LoadObjectFromFrame(f, kStandardFrameFunctionOffset);
57  return %RawDownCast<JSFunction>(result);
58}
59
60const kStandardFrameCallerFPOffset: constexpr int31
61    generates 'StandardFrameConstants::kCallerFPOffset';
62operator '.caller' macro LoadCallerFromFrame(f: Frame): Frame {
63  const result: RawPtr = LoadPointerFromFrame(f, kStandardFrameCallerFPOffset);
64  return %RawDownCast<Frame>(result);
65}
66
67const kStandardFrameArgCOffset: constexpr int31
68    generates 'StandardFrameConstants::kArgCOffset';
69const kJSArgcReceiverSlots: constexpr int31
70    generates 'kJSArgcReceiverSlots';
71
72operator '.argument_count' macro LoadArgCFromFrame(f: Frame): intptr {
73  return LoadIntptrFromFrame(f, kStandardFrameArgCOffset) -
74      kJSArgcReceiverSlots;
75}
76
77type ContextOrFrameType = Context|FrameType;
78Cast<ContextOrFrameType>(implicit context: Context)(o: Object):
79    ContextOrFrameType
80    labels CastError {
81  typeswitch (o) {
82    case (c: Context): {
83      return c;
84    }
85    case (t: FrameType): {
86      return t;
87    }
88    case (Object): {
89      goto CastError;
90    }
91  }
92}
93
94const kStandardFrameContextOrFrameTypeOffset: constexpr int31
95    generates 'StandardFrameConstants::kContextOrFrameTypeOffset';
96operator '.context_or_frame_type'
97macro LoadContextOrFrameTypeFromFrame(implicit context: Context)(f: Frame):
98    ContextOrFrameType {
99  return UnsafeCast<ContextOrFrameType>(
100      LoadObjectFromFrame(f, kStandardFrameContextOrFrameTypeOffset));
101}
102
103operator '==' macro FrameTypeEquals(f1: FrameType, f2: FrameType): bool {
104  return TaggedEqual(f1, f2);
105}
106
107macro Cast<A : type extends Frame>(implicit context: Context)(o: Frame):
108    A labels CastError;
109Cast<StandardFrame>(implicit context: Context)(f: Frame):
110    StandardFrame labels CastError {
111  const o: HeapObject =
112      Cast<HeapObject>(f.context_or_frame_type) otherwise CastError;
113  // StandardFrames (which include interpreted and JIT-compiled frames),
114  // unlike other frame types, don't have their own type marker stored in
115  // the frame, but rather have the function's context stored where the
116  // type marker is stored for other frame types. From Torque, it would
117  // be quite expensive to do the test required to distinguish interpreter
118  // frames from JITted ones (and other StandardFrame types), so
119  // StandardFrame is the level of granularity support when iterating the
120  // stack from generated code.
121  // See the descriptions and frame layouts in src/frame-constants.h.
122  if (IsContext(o)) {
123    return %RawDownCast<StandardFrame>(f);
124  }
125  goto CastError;
126}
127
128// Load target function from the current JS frame.
129// This is an alternative way of getting the target function in addition to
130// Parameter(Descriptor::kJSTarget). The latter should be used near the
131// beginning of builtin code while the target value is still in the register
132// and the former should be used in slow paths in order to reduce register
133// pressure on the fast path.
134@export
135macro LoadTargetFromFrame(): JSFunction {
136  return LoadFramePointer().function;
137}
138