code-factory.cc 16.5 KB
Newer Older
1 2 3 4
// Copyright 2014 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.

5
#include "src/code-factory.h"
6 7 8 9 10 11 12

#include "src/bootstrapper.h"
#include "src/ic/ic.h"

namespace v8 {
namespace internal {

ishell's avatar
ishell committed
13 14 15 16 17 18 19 20 21 22
namespace {

// TODO(ishell): make it (const Stub& stub) once CodeStub::GetCode() is const.
template <typename Stub>
Callable make_callable(Stub& stub) {
  typedef typename Stub::Descriptor Descriptor;
  return Callable(stub.GetCode(), Descriptor(stub.isolate()));
}

}  // namespace
23

24
// static
25
Callable CodeFactory::LoadIC(Isolate* isolate) {
26
  if (FLAG_tf_load_ic_stub) {
ishell's avatar
ishell committed
27
    LoadICTrampolineTFStub stub(isolate);
ishell's avatar
ishell committed
28
    return make_callable(stub);
29
  }
ishell's avatar
ishell committed
30
  LoadICTrampolineStub stub(isolate);
ishell's avatar
ishell committed
31
  return make_callable(stub);
32 33
}

34 35 36
// static
Callable CodeFactory::ApiGetter(Isolate* isolate) {
  CallApiGetterStub stub(isolate);
ishell's avatar
ishell committed
37
  return make_callable(stub);
38
}
39

40
// static
41
Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate) {
ishell's avatar
ishell committed
42 43 44 45 46 47
  if (FLAG_tf_load_ic_stub) {
    LoadICTFStub stub(isolate);
    return make_callable(stub);
  }
  LoadICStub stub(isolate);
  return make_callable(stub);
48 49
}

50 51
// static
Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) {
ishell's avatar
ishell committed
52
  LoadGlobalICTrampolineStub stub(isolate, LoadGlobalICState(typeof_mode));
ishell's avatar
ishell committed
53
  return make_callable(stub);
54 55 56 57 58
}

// static
Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
                                                  TypeofMode typeof_mode) {
ishell's avatar
ishell committed
59 60
  LoadGlobalICStub stub(isolate, LoadGlobalICState(typeof_mode));
  return make_callable(stub);
61
}
62

63
// static
64
Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
65 66
  if (FLAG_tf_load_ic_stub) {
    KeyedLoadICTrampolineTFStub stub(isolate);
ishell's avatar
ishell committed
67
    return make_callable(stub);
68
  }
ishell's avatar
ishell committed
69
  KeyedLoadICTrampolineStub stub(isolate);
ishell's avatar
ishell committed
70
  return make_callable(stub);
71 72
}

73
// static
74
Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
ishell's avatar
ishell committed
75 76 77 78 79 80
  if (FLAG_tf_load_ic_stub) {
    KeyedLoadICTFStub stub(isolate);
    return make_callable(stub);
  }
  KeyedLoadICStub stub(isolate);
  return make_callable(stub);
81 82
}

83 84 85 86 87
// static
Callable CodeFactory::KeyedLoadIC_Megamorphic(Isolate* isolate) {
  return Callable(isolate->builtins()->KeyedLoadIC_Megamorphic(),
                  LoadWithVectorDescriptor(isolate));
}
88

89
// static
90
Callable CodeFactory::CallIC(Isolate* isolate, int argc,
ishell's avatar
ishell committed
91 92
                             ConvertReceiverMode mode,
                             TailCallMode tail_call_mode) {
verwaest's avatar
verwaest committed
93
  CallICTrampolineStub stub(isolate, CallICState(argc, mode, tail_call_mode));
ishell's avatar
ishell committed
94
  return make_callable(stub);
95 96 97
}

// static
98
Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc,
ishell's avatar
ishell committed
99 100
                                            ConvertReceiverMode mode,
                                            TailCallMode tail_call_mode) {
ishell's avatar
ishell committed
101 102
  CallICStub stub(isolate, CallICState(argc, mode, tail_call_mode));
  return make_callable(stub);
103 104
}

105
// static
106
Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
107
  StoreICTrampolineStub stub(isolate, StoreICState(language_mode));
ishell's avatar
ishell committed
108
  return make_callable(stub);
109 110 111
}

// static
112 113
Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
                                             LanguageMode language_mode) {
ishell's avatar
ishell committed
114 115
  StoreICStub stub(isolate, StoreICState(language_mode));
  return make_callable(stub);
116 117 118
}

// static
119 120
Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
                                   LanguageMode language_mode) {
121
  KeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode));
ishell's avatar
ishell committed
122
  return make_callable(stub);
123 124 125
}

// static
126 127
Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate,
                                                  LanguageMode language_mode) {
ishell's avatar
ishell committed
128 129
  KeyedStoreICStub stub(isolate, StoreICState(language_mode));
  return make_callable(stub);
130 131 132
}

// static
133
Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
ishell's avatar
ishell committed
134 135
  CompareICStub stub(isolate, op);
  return make_callable(stub);
136 137 138
}

// static
139 140
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
  BinaryOpICStub stub(isolate, op);
ishell's avatar
ishell committed
141
  return make_callable(stub);
142 143
}

144
// static
145 146
Callable CodeFactory::InstanceOf(Isolate* isolate) {
  InstanceOfStub stub(isolate);
ishell's avatar
ishell committed
147
  return make_callable(stub);
148 149
}

150 151 152
// static
Callable CodeFactory::GetProperty(Isolate* isolate) {
  GetPropertyStub stub(isolate);
ishell's avatar
ishell committed
153
  return make_callable(stub);
154 155
}

156
// static
157
Callable CodeFactory::ToBoolean(Isolate* isolate) {
158 159
  return Callable(isolate->builtins()->ToBoolean(),
                  TypeConversionDescriptor(isolate));
160 161 162 163
}

// static
Callable CodeFactory::ToNumber(Isolate* isolate) {
164 165
  return Callable(isolate->builtins()->ToNumber(),
                  TypeConversionDescriptor(isolate));
166 167
}

168 169
// static
Callable CodeFactory::NonNumberToNumber(Isolate* isolate) {
170 171
  return Callable(isolate->builtins()->NonNumberToNumber(),
                  TypeConversionDescriptor(isolate));
172 173 174 175
}

// static
Callable CodeFactory::StringToNumber(Isolate* isolate) {
176 177
  return Callable(isolate->builtins()->StringToNumber(),
                  TypeConversionDescriptor(isolate));
178 179
}

180 181 182
// static
Callable CodeFactory::ToString(Isolate* isolate) {
  ToStringStub stub(isolate);
ishell's avatar
ishell committed
183
  return make_callable(stub);
184 185
}

186 187 188
// static
Callable CodeFactory::ToName(Isolate* isolate) {
  ToNameStub stub(isolate);
ishell's avatar
ishell committed
189
  return make_callable(stub);
190 191
}

192 193 194
// static
Callable CodeFactory::ToInteger(Isolate* isolate) {
  ToIntegerStub stub(isolate);
ishell's avatar
ishell committed
195
  return make_callable(stub);
196 197
}

198 199 200
// static
Callable CodeFactory::ToLength(Isolate* isolate) {
  ToLengthStub stub(isolate);
ishell's avatar
ishell committed
201
  return make_callable(stub);
202 203
}

204 205 206
// static
Callable CodeFactory::ToObject(Isolate* isolate) {
  ToObjectStub stub(isolate);
ishell's avatar
ishell committed
207
  return make_callable(stub);
208 209
}

210 211 212 213 214 215 216 217 218 219 220 221 222
// static
Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate,
                                              ToPrimitiveHint hint) {
  return Callable(isolate->builtins()->NonPrimitiveToPrimitive(hint),
                  TypeConversionDescriptor(isolate));
}

// static
Callable CodeFactory::OrdinaryToPrimitive(Isolate* isolate,
                                          OrdinaryToPrimitiveHint hint) {
  return Callable(isolate->builtins()->OrdinaryToPrimitive(hint),
                  TypeConversionDescriptor(isolate));
}
223

224 225 226
// static
Callable CodeFactory::NumberToString(Isolate* isolate) {
  NumberToStringStub stub(isolate);
ishell's avatar
ishell committed
227
  return make_callable(stub);
228 229 230 231 232
}

// static
Callable CodeFactory::RegExpConstructResult(Isolate* isolate) {
  RegExpConstructResultStub stub(isolate);
ishell's avatar
ishell committed
233
  return make_callable(stub);
234 235
}

236 237 238 239 240 241
// static
Callable CodeFactory::RegExpExec(Isolate* isolate) {
  RegExpExecStub stub(isolate);
  return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}

242 243 244
// static
Callable CodeFactory::Add(Isolate* isolate) {
  AddStub stub(isolate);
ishell's avatar
ishell committed
245
  return make_callable(stub);
246 247 248 249 250
}

// static
Callable CodeFactory::Subtract(Isolate* isolate) {
  SubtractStub stub(isolate);
ishell's avatar
ishell committed
251
  return make_callable(stub);
252 253
}

254 255 256
// static
Callable CodeFactory::Multiply(Isolate* isolate) {
  MultiplyStub stub(isolate);
ishell's avatar
ishell committed
257
  return make_callable(stub);
258 259
}

260 261 262
// static
Callable CodeFactory::Divide(Isolate* isolate) {
  DivideStub stub(isolate);
ishell's avatar
ishell committed
263
  return make_callable(stub);
264 265
}

266 267 268
// static
Callable CodeFactory::Modulus(Isolate* isolate) {
  ModulusStub stub(isolate);
ishell's avatar
ishell committed
269
  return make_callable(stub);
270
}
271 272 273 274

// static
Callable CodeFactory::ShiftRight(Isolate* isolate) {
  ShiftRightStub stub(isolate);
ishell's avatar
ishell committed
275
  return make_callable(stub);
276 277 278 279 280
}

// static
Callable CodeFactory::ShiftRightLogical(Isolate* isolate) {
  ShiftRightLogicalStub stub(isolate);
ishell's avatar
ishell committed
281
  return make_callable(stub);
282 283 284 285 286
}

// static
Callable CodeFactory::ShiftLeft(Isolate* isolate) {
  ShiftLeftStub stub(isolate);
ishell's avatar
ishell committed
287
  return make_callable(stub);
288
}
289

290 291 292
// static
Callable CodeFactory::BitwiseAnd(Isolate* isolate) {
  BitwiseAndStub stub(isolate);
ishell's avatar
ishell committed
293
  return make_callable(stub);
294 295 296 297 298
}

// static
Callable CodeFactory::BitwiseOr(Isolate* isolate) {
  BitwiseOrStub stub(isolate);
ishell's avatar
ishell committed
299
  return make_callable(stub);
300 301 302 303 304
}

// static
Callable CodeFactory::BitwiseXor(Isolate* isolate) {
  BitwiseXorStub stub(isolate);
ishell's avatar
ishell committed
305
  return make_callable(stub);
306 307
}

308 309 310
// static
Callable CodeFactory::Inc(Isolate* isolate) {
  IncStub stub(isolate);
ishell's avatar
ishell committed
311
  return make_callable(stub);
312 313 314 315 316
}

// static
Callable CodeFactory::Dec(Isolate* isolate) {
  DecStub stub(isolate);
ishell's avatar
ishell committed
317
  return make_callable(stub);
318 319
}

320 321 322
// static
Callable CodeFactory::LessThan(Isolate* isolate) {
  LessThanStub stub(isolate);
ishell's avatar
ishell committed
323
  return make_callable(stub);
324 325 326 327 328
}

// static
Callable CodeFactory::LessThanOrEqual(Isolate* isolate) {
  LessThanOrEqualStub stub(isolate);
ishell's avatar
ishell committed
329
  return make_callable(stub);
330 331 332 333 334
}

// static
Callable CodeFactory::GreaterThan(Isolate* isolate) {
  GreaterThanStub stub(isolate);
ishell's avatar
ishell committed
335
  return make_callable(stub);
336 337 338 339 340
}

// static
Callable CodeFactory::GreaterThanOrEqual(Isolate* isolate) {
  GreaterThanOrEqualStub stub(isolate);
ishell's avatar
ishell committed
341
  return make_callable(stub);
342 343 344 345 346
}

// static
Callable CodeFactory::Equal(Isolate* isolate) {
  EqualStub stub(isolate);
ishell's avatar
ishell committed
347
  return make_callable(stub);
348 349 350 351 352
}

// static
Callable CodeFactory::NotEqual(Isolate* isolate) {
  NotEqualStub stub(isolate);
ishell's avatar
ishell committed
353
  return make_callable(stub);
354 355
}

356 357 358
// static
Callable CodeFactory::StrictEqual(Isolate* isolate) {
  StrictEqualStub stub(isolate);
ishell's avatar
ishell committed
359
  return make_callable(stub);
360
}
361

362 363 364
// static
Callable CodeFactory::StrictNotEqual(Isolate* isolate) {
  StrictNotEqualStub stub(isolate);
ishell's avatar
ishell committed
365
  return make_callable(stub);
366 367
}

368 369 370 371
// static
Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
                                PretenureFlag pretenure_flag) {
  StringAddStub stub(isolate, flags, pretenure_flag);
ishell's avatar
ishell committed
372
  return make_callable(stub);
373 374
}

375
// static
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
Callable CodeFactory::StringCompare(Isolate* isolate, Token::Value token) {
  switch (token) {
    case Token::EQ:
    case Token::EQ_STRICT:
      return StringEqual(isolate);
    case Token::NE:
    case Token::NE_STRICT:
      return StringNotEqual(isolate);
    case Token::LT:
      return StringLessThan(isolate);
    case Token::GT:
      return StringGreaterThan(isolate);
    case Token::LTE:
      return StringLessThanOrEqual(isolate);
    case Token::GTE:
      return StringGreaterThanOrEqual(isolate);
    default:
      break;
  }
  UNREACHABLE();
  return StringEqual(isolate);
397 398
}

399 400 401
// static
Callable CodeFactory::StringEqual(Isolate* isolate) {
  StringEqualStub stub(isolate);
ishell's avatar
ishell committed
402
  return make_callable(stub);
403 404 405 406 407
}

// static
Callable CodeFactory::StringNotEqual(Isolate* isolate) {
  StringNotEqualStub stub(isolate);
ishell's avatar
ishell committed
408
  return make_callable(stub);
409
}
410

411 412 413
// static
Callable CodeFactory::StringLessThan(Isolate* isolate) {
  StringLessThanStub stub(isolate);
ishell's avatar
ishell committed
414
  return make_callable(stub);
415 416 417 418 419
}

// static
Callable CodeFactory::StringLessThanOrEqual(Isolate* isolate) {
  StringLessThanOrEqualStub stub(isolate);
ishell's avatar
ishell committed
420
  return make_callable(stub);
421 422 423 424 425
}

// static
Callable CodeFactory::StringGreaterThan(Isolate* isolate) {
  StringGreaterThanStub stub(isolate);
ishell's avatar
ishell committed
426
  return make_callable(stub);
427 428 429 430 431
}

// static
Callable CodeFactory::StringGreaterThanOrEqual(Isolate* isolate) {
  StringGreaterThanOrEqualStub stub(isolate);
ishell's avatar
ishell committed
432
  return make_callable(stub);
433 434
}

435 436 437 438 439 440
// static
Callable CodeFactory::SubString(Isolate* isolate) {
  SubStringStub stub(isolate);
  return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}

441 442 443 444 445 446
// static
Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
  return Callable(isolate->builtins()->ResumeGeneratorTrampoline(),
                  ResumeGeneratorDescriptor(isolate));
}

447 448 449
// static
Callable CodeFactory::Typeof(Isolate* isolate) {
  TypeofStub stub(isolate);
ishell's avatar
ishell committed
450
  return make_callable(stub);
451 452
}

453 454 455
// static
Callable CodeFactory::FastCloneRegExp(Isolate* isolate) {
  FastCloneRegExpStub stub(isolate);
ishell's avatar
ishell committed
456
  return make_callable(stub);
457 458
}

459 460 461 462
// static
Callable CodeFactory::FastCloneShallowArray(Isolate* isolate) {
  // TODO(mstarzinger): Thread through AllocationSiteMode at some point.
  FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE);
ishell's avatar
ishell committed
463
  return make_callable(stub);
464 465 466 467 468
}

// static
Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) {
  FastCloneShallowObjectStub stub(isolate, length);
ishell's avatar
ishell committed
469
  return make_callable(stub);
470 471 472
}


473
// static
474 475
Callable CodeFactory::FastNewFunctionContext(Isolate* isolate) {
  FastNewFunctionContextStub stub(isolate);
ishell's avatar
ishell committed
476
  return make_callable(stub);
477 478
}

479
// static
480 481
Callable CodeFactory::FastNewClosure(Isolate* isolate) {
  FastNewClosureStub stub(isolate);
ishell's avatar
ishell committed
482
  return make_callable(stub);
483 484 485 486 487
}

// static
Callable CodeFactory::FastNewObject(Isolate* isolate) {
  FastNewObjectStub stub(isolate);
ishell's avatar
ishell committed
488
  return make_callable(stub);
489 490
}

491
// static
492 493 494
Callable CodeFactory::FastNewRestParameter(Isolate* isolate,
                                           bool skip_stub_frame) {
  FastNewRestParameterStub stub(isolate, skip_stub_frame);
ishell's avatar
ishell committed
495
  return make_callable(stub);
496 497
}

498
// static
499 500 501
Callable CodeFactory::FastNewSloppyArguments(Isolate* isolate,
                                             bool skip_stub_frame) {
  FastNewSloppyArgumentsStub stub(isolate, skip_stub_frame);
ishell's avatar
ishell committed
502
  return make_callable(stub);
503 504
}

505
// static
506 507 508
Callable CodeFactory::FastNewStrictArguments(Isolate* isolate,
                                             bool skip_stub_frame) {
  FastNewStrictArgumentsStub stub(isolate, skip_stub_frame);
ishell's avatar
ishell committed
509
  return make_callable(stub);
510 511
}

512
// static
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
Callable CodeFactory::CopyFastSmiOrObjectElements(Isolate* isolate) {
  return Callable(isolate->builtins()->CopyFastSmiOrObjectElements(),
                  CopyFastSmiOrObjectElementsDescriptor(isolate));
}

// static
Callable CodeFactory::GrowFastDoubleElements(Isolate* isolate) {
  return Callable(isolate->builtins()->GrowFastDoubleElements(),
                  GrowArrayElementsDescriptor(isolate));
}

// static
Callable CodeFactory::GrowFastSmiOrObjectElements(Isolate* isolate) {
  return Callable(isolate->builtins()->GrowFastSmiOrObjectElements(),
                  GrowArrayElementsDescriptor(isolate));
528 529
}

530 531 532
// static
Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
  AllocateHeapNumberStub stub(isolate);
ishell's avatar
ishell committed
533
  return make_callable(stub);
534 535
}

ishell's avatar
ishell committed
536 537 538 539
#define SIMD128_ALLOC(TYPE, Type, type, lane_count, lane_type) \
  Callable CodeFactory::Allocate##Type(Isolate* isolate) {     \
    Allocate##Type##Stub stub(isolate);                        \
    return make_callable(stub);                                \
bbudge's avatar
bbudge committed
540 541 542
  }
SIMD128_TYPES(SIMD128_ALLOC)
#undef SIMD128_ALLOC
543

544 545 546 547 548 549
// static
Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
  return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(),
                  ArgumentAdaptorDescriptor(isolate));
}

550
// static
551 552 553
Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode,
                           TailCallMode tail_call_mode) {
  return Callable(isolate->builtins()->Call(mode, tail_call_mode),
554 555 556
                  CallTrampolineDescriptor(isolate));
}

557
// static
558 559
Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) {
  return Callable(isolate->builtins()->CallFunction(mode),
560 561 562
                  CallTrampolineDescriptor(isolate));
}

563 564 565 566 567 568
// static
Callable CodeFactory::Construct(Isolate* isolate) {
  return Callable(isolate->builtins()->Construct(),
                  ConstructTrampolineDescriptor(isolate));
}

569 570 571 572 573 574
// static
Callable CodeFactory::ConstructFunction(Isolate* isolate) {
  return Callable(isolate->builtins()->ConstructFunction(),
                  ConstructTrampolineDescriptor(isolate));
}

575 576 577
// static
Callable CodeFactory::HasProperty(Isolate* isolate) {
  HasPropertyStub stub(isolate);
ishell's avatar
ishell committed
578
  return make_callable(stub);
579
}
580

581 582 583
// static
Callable CodeFactory::ForInFilter(Isolate* isolate) {
  ForInFilterStub stub(isolate);
ishell's avatar
ishell committed
584
  return make_callable(stub);
585 586
}

587
// static
588
Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
589 590 591 592 593
                                                 TailCallMode tail_call_mode,
                                                 CallableType function_type) {
  return Callable(isolate->builtins()->InterpreterPushArgsAndCall(
                      tail_call_mode, function_type),
                  InterpreterPushArgsAndCallDescriptor(isolate));
594 595
}

596
// static
597 598 599
Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
  return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),
                  InterpreterPushArgsAndConstructDescriptor(isolate));
600 601
}

602
// static
603
Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
604 605
  // Note: If we ever use fpregs in the interpreter then we will need to
  // save fpregs too.
606
  CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister);
607
  return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate));
608 609
}

610 611 612 613 614 615
// static
Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
  return Callable(isolate->builtins()->InterpreterOnStackReplacement(),
                  ContextOnlyDescriptor(isolate));
}

616 617
}  // namespace internal
}  // namespace v8