• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 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
5namespace internal {
6
7namespace runtime {
8extern runtime GetTemplateObject(implicit context: Context)(
9    TemplateObjectDescription, SharedFunctionInfo, Smi): JSAny;
10extern runtime BytecodeBudgetInterruptFromCode(implicit context: Context)(
11    FeedbackCell): JSAny;
12}
13
14builtin GetTemplateObject(
15    context: Context, shared: SharedFunctionInfo,
16    description: TemplateObjectDescription, slot: uintptr,
17    maybeFeedbackVector: Undefined|FeedbackVector): JSArray {
18  // TODO(jgruber): Consider merging with the GetTemplateObject bytecode
19  // handler; the current advantage of the split implementation is that the
20  // bytecode can skip most work if feedback exists.
21
22  // TODO(v8:9891): Remove this assert once all callers are ported to Torque.
23  // This assert ensures correctness of maybeFeedbackVector's type which can
24  // be easily broken for calls from CSA.
25  assert(
26      IsUndefined(maybeFeedbackVector) ||
27      Is<FeedbackVector>(maybeFeedbackVector));
28  try {
29    const vector =
30        Cast<FeedbackVector>(maybeFeedbackVector) otherwise CallRuntime;
31    return Cast<JSArray>(ic::LoadFeedbackVectorSlot(vector, slot))
32        otherwise CallRuntime;
33  } label CallRuntime deferred {
34    const result = UnsafeCast<JSArray>(runtime::GetTemplateObject(
35        description, shared, Convert<Smi>(Signed(slot))));
36    const vector =
37        Cast<FeedbackVector>(maybeFeedbackVector) otherwise return result;
38    ic::StoreFeedbackVectorSlot(vector, slot, result);
39    return result;
40  }
41}
42
43builtin BytecodeBudgetInterruptFromCode(implicit context: Context)(
44    feedbackCell: FeedbackCell): Object {
45  // The runtime call is wrapped by a builtin since the calling sequence in
46  // generated code is shorter for builtins than for runtime calls.
47  tail runtime::BytecodeBudgetInterruptFromCode(feedbackCell);
48}
49
50extern transitioning macro ForInPrepareForTorque(
51    Map | FixedArray, uintptr, Undefined | FeedbackVector): FixedArray;
52
53transitioning builtin ForInPrepare(implicit _context: Context)(
54    enumerator: Map|FixedArray, slot: uintptr,
55    maybeFeedbackVector: Undefined|FeedbackVector): FixedArray {
56  return ForInPrepareForTorque(enumerator, slot, maybeFeedbackVector);
57}
58
59extern transitioning builtin ForInFilter(implicit context: Context)(
60    JSAny, HeapObject): JSAny;
61extern enum ForInFeedback extends uint31 { kAny, ...}
62extern macro UpdateFeedback(
63    SmiTagged<ForInFeedback>, Undefined | FeedbackVector, uintptr);
64
65@export
66transitioning macro ForInNextSlow(
67    context: Context, slot: uintptr, receiver: JSAnyNotSmi, key: JSAny,
68    cacheType: Object, maybeFeedbackVector: Undefined|FeedbackVector): JSAny {
69  assert(receiver.map != cacheType);  // Handled on the fast path.
70  UpdateFeedback(
71      SmiTag<ForInFeedback>(ForInFeedback::kAny), maybeFeedbackVector, slot);
72  return ForInFilter(key, receiver);
73}
74
75// Note: the untagged {slot} parameter must be in the first couple of args to
76// guarantee it's allocated in a register.
77transitioning builtin ForInNext(
78    context: Context, slot: uintptr, receiver: JSAnyNotSmi,
79    cacheArray: FixedArray, cacheType: Object, cacheIndex: Smi,
80    maybeFeedbackVector: Undefined|FeedbackVector): JSAny {
81  // Load the next key from the enumeration array.
82  const key = UnsafeCast<JSAny>(cacheArray.objects[cacheIndex]);
83
84  if (receiver.map == cacheType) {
85    // The enum cache is in use for {receiver}, the {key} is definitely valid.
86    return key;
87  }
88
89  return ForInNextSlow(
90      context, slot, receiver, key, cacheType, maybeFeedbackVector);
91}
92
93}  // namespace internal
94