interface-descriptors.cc 13.8 KB
Newer Older
1 2 3 4 5 6
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/interface-descriptors.h"

7 8
#include "src/macro-assembler.h"

9 10 11
namespace v8 {
namespace internal {

12
void CallInterfaceDescriptorData::InitializePlatformSpecific(
13
    int register_parameter_count, const Register* registers) {
14 15
  DCHECK(!IsInitializedPlatformIndependent());

16 17
  register_param_count_ = register_parameter_count;

18 19 20
  // UBSan doesn't like creating zero-length arrays.
  if (register_parameter_count == 0) return;

21
  // InterfaceDescriptor owns a copy of the registers array.
22
  register_params_ = NewArray<Register>(register_parameter_count, no_reg);
23
  for (int i = 0; i < register_parameter_count; i++) {
24 25 26
    // The value of the root register must be reserved, thus any uses
    // within the calling convention are disallowed.
    DCHECK_NE(registers[i], kRootRegister);
27 28 29 30
    register_params_[i] = registers[i];
  }
}

31
void CallInterfaceDescriptorData::InitializePlatformIndependent(
32 33
    Flags flags, int return_count, int parameter_count,
    const MachineType* machine_types, int machine_types_length) {
34 35
  DCHECK(IsInitializedPlatformSpecific());

36
  flags_ = flags;
37 38
  return_count_ = return_count;
  param_count_ = parameter_count;
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
  const int types_length = return_count_ + param_count_;

  // Machine types are either fully initialized or null.
  if (machine_types == nullptr) {
    machine_types_ =
        NewArray<MachineType>(types_length, MachineType::AnyTagged());
  } else {
    DCHECK_EQ(machine_types_length, types_length);
    machine_types_ = NewArray<MachineType>(types_length);
    for (int i = 0; i < types_length; i++) machine_types_[i] = machine_types[i];
  }

  DCHECK(AllStackParametersAreTagged());
}

#ifdef DEBUG
bool CallInterfaceDescriptorData::AllStackParametersAreTagged() const {
  DCHECK(IsInitialized());
  const int types_length = return_count_ + param_count_;
  const int first_stack_param = return_count_ + register_param_count_;
  for (int i = first_stack_param; i < types_length; i++) {
    if (!machine_types_[i].IsTagged()) return false;
61
  }
62
  return true;
63
}
64
#endif  // DEBUG
65

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
void CallInterfaceDescriptorData::Reset() {
  delete[] machine_types_;
  machine_types_ = nullptr;
  delete[] register_params_;
  register_params_ = nullptr;
}

// static
CallInterfaceDescriptorData
    CallDescriptors::call_descriptor_data_[NUMBER_OF_DESCRIPTORS];

void CallDescriptors::InitializeOncePerProcess() {
#define INTERFACE_DESCRIPTOR(name, ...) \
  name##Descriptor().Initialize(&call_descriptor_data_[CallDescriptors::name]);
  INTERFACE_DESCRIPTOR_LIST(INTERFACE_DESCRIPTOR)
#undef INTERFACE_DESCRIPTOR
82 83 84 85 86

  DCHECK(ContextOnlyDescriptor{}.HasContextParameter());
  DCHECK(!NoContextDescriptor{}.HasContextParameter());
  DCHECK(!AllocateDescriptor{}.HasContextParameter());
  DCHECK(!AllocateHeapNumberDescriptor{}.HasContextParameter());
87
  DCHECK(!AbortDescriptor{}.HasContextParameter());
88 89 90 91 92 93 94 95
}

void CallDescriptors::TearDown() {
  for (CallInterfaceDescriptorData& data : call_descriptor_data_) {
    data.Reset();
  }
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
void CallInterfaceDescriptor::JSDefaultInitializePlatformSpecific(
    CallInterfaceDescriptorData* data, int non_js_register_parameter_count) {
  DCHECK_LE(static_cast<unsigned>(non_js_register_parameter_count), 1);

  // 3 is for kTarget, kNewTarget and kActualArgumentsCount
  int register_parameter_count = 3 + non_js_register_parameter_count;

  DCHECK(!AreAliased(
      kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
      kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register));

  const Register default_js_stub_registers[] = {
      kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
      kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register};

  CHECK_LE(static_cast<size_t>(register_parameter_count),
           arraysize(default_js_stub_registers));
  data->InitializePlatformSpecific(register_parameter_count,
                                   default_js_stub_registers);
}

117 118
const char* CallInterfaceDescriptor::DebugName() const {
  CallDescriptors::Key key = CallDescriptors::GetKey(data_);
119
  switch (key) {
120 121 122
#define DEF_CASE(name, ...)   \
  case CallDescriptors::name: \
    return #name " Descriptor";
123 124 125 126 127 128 129 130 131
    INTERFACE_DESCRIPTOR_LIST(DEF_CASE)
#undef DEF_CASE
    case CallDescriptors::NUMBER_OF_DESCRIPTORS:
      break;
  }
  return "";
}


132 133 134 135 136
void VoidDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  data->InitializePlatformSpecific(0, nullptr);
}

137 138 139 140 141 142
void AllocateDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {kAllocateSizeRegister};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

143 144 145 146 147 148 149
void CEntry1ArgvOnStackDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {kRuntimeCallArgCountRegister,
                          kRuntimeCallFunctionRegister};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
namespace {

void InterpreterCEntryDescriptor_InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {kRuntimeCallArgCountRegister,
                          kRuntimeCallArgvRegister,
                          kRuntimeCallFunctionRegister};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

}  // namespace

void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}

void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}

172 173
void FastNewFunctionContextDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
174
  Register registers[] = {ScopeInfoRegister(), SlotsRegister()};
175 176 177
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

178 179 180 181 182 183 184 185 186 187 188 189 190 191
void FastNewObjectDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {TargetRegister(), NewTargetRegister()};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

const Register FastNewObjectDescriptor::TargetRegister() {
  return kJSFunctionRegister;
}

const Register FastNewObjectDescriptor::NewTargetRegister() {
  return kJavaScriptCallNewTargetRegister;
}

192 193 194

void LoadDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
195
  Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister()};
196
  data->InitializePlatformSpecific(arraysize(registers), registers);
197 198
}

199 200
void LoadGlobalDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
201
  Register registers[] = {NameRegister(), SlotRegister()};
202 203 204 205
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

void LoadGlobalWithVectorDescriptor::InitializePlatformSpecific(
206
    CallInterfaceDescriptorData* data) {
207
  Register registers[] = {NameRegister(), SlotRegister(), VectorRegister()};
208 209
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
210

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
void StoreGlobalDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {NameRegister(), ValueRegister(), SlotRegister()};

  int len = arraysize(registers) - kStackArgumentsCount;
  data->InitializePlatformSpecific(len, registers);
}

void StoreGlobalWithVectorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {NameRegister(), ValueRegister(), SlotRegister(),
                          VectorRegister()};
  int len = arraysize(registers) - kStackArgumentsCount;
  data->InitializePlatformSpecific(len, registers);
}

227 228
void StoreDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
229 230
  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
                          SlotRegister()};
231

232 233
  int len = arraysize(registers) - kStackArgumentsCount;
  data->InitializePlatformSpecific(len, registers);
234 235
}

236
void StoreTransitionDescriptor::InitializePlatformSpecific(
237
    CallInterfaceDescriptorData* data) {
238 239 240 241
  Register registers[] = {
      ReceiverRegister(), NameRegister(), MapRegister(),
      ValueRegister(),    SlotRegister(), VectorRegister(),
  };
242
  int len = arraysize(registers) - kStackArgumentsCount;
243
  data->InitializePlatformSpecific(len, registers);
244 245
}

246
void StringAtDescriptor::InitializePlatformSpecific(
247 248 249 250
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

251 252 253 254 255
void StringSubstringDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

256
void TypeConversionDescriptor::InitializePlatformSpecific(
257
    CallInterfaceDescriptorData* data) {
258
  Register registers[] = {ArgumentRegister()};
259 260 261
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

262 263 264 265 266
void TypeConversionStackParameterDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  data->InitializePlatformSpecific(0, nullptr);
}

267 268 269 270 271
void AsyncFunctionStackParameterDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  data->InitializePlatformSpecific(0, nullptr);
}

272 273
void LoadWithVectorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
274 275
  Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
                          VectorRegister()};
276 277 278 279 280 281
  // TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
  // to allow no_reg entries.
  // DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), SlotRegister(),
  //                    VectorRegister(), kRootRegister));
  int len = arraysize(registers) - kStackArgumentsCount;
  data->InitializePlatformSpecific(len, registers);
282 283
}

284
void StoreWithVectorDescriptor::InitializePlatformSpecific(
285
    CallInterfaceDescriptorData* data) {
286 287
  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
                          SlotRegister(), VectorRegister()};
288 289 290
  // TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
  // to allow no_reg entries.
  // DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), kRootRegister));
291 292
  int len = arraysize(registers) - kStackArgumentsCount;
  data->InitializePlatformSpecific(len, registers);
293 294
}

295 296
const Register ApiGetterDescriptor::ReceiverRegister() {
  return LoadDescriptor::ReceiverRegister();
297 298 299 300
}

void ApiGetterDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
301 302
  Register registers[] = {ReceiverRegister(), HolderRegister(),
                          CallbackRegister()};
303
  data->InitializePlatformSpecific(arraysize(registers), registers);
304 305
}

306 307
void ContextOnlyDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
308
  data->InitializePlatformSpecific(0, nullptr);
309 310
}

311 312 313 314 315
void NoContextDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  data->InitializePlatformSpecific(0, nullptr);
}

316
void GrowArrayElementsDescriptor::InitializePlatformSpecific(
317
    CallInterfaceDescriptorData* data) {
318
  Register registers[] = {ObjectRegister(), KeyRegister()};
319 320 321
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

322 323
void NewArgumentsElementsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
324
  DefaultInitializePlatformSpecific(data, 3);
325 326
}

327 328 329 330 331 332 333 334 335 336 337 338 339 340
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // This descriptor must use the same set of registers as the
  // ArrayNArgumentsConstructorDescriptor.
  ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
}

void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // This descriptor must use the same set of registers as the
  // ArrayNArgumentsConstructorDescriptor.
  ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
}

341 342 343 344 345 346 347 348 349 350 351
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // Keep the arguments on the same registers as they were in
  // ArrayConstructorDescriptor to avoid unnecessary register moves.
  // kFunction, kAllocationSite, kActualArgumentsCount
  Register registers[] = {kJavaScriptCallTargetRegister,
                          kJavaScriptCallExtraArg1Register,
                          kJavaScriptCallArgCountRegister};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

352
void WasmMemoryGrowDescriptor::InitializePlatformSpecific(
353 354 355
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}
356

357 358 359 360 361
void WasmThrowDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

362 363 364 365 366
void WasmAtomicWakeDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

367 368 369 370 371
void WasmI32AtomicWaitDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

372 373 374 375 376
void WasmI64AtomicWaitDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

377 378 379 380 381
void CloneObjectWithVectorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

382 383 384 385 386 387 388 389 390 391
void BigIntToWasmI64Descriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

void BigIntToI64Descriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  DefaultInitializePlatformSpecific(data, kParameterCount);
}

392 393
}  // namespace internal
}  // namespace v8