Home | History | Annotate | Download | only in src
      1 // Copyright 2014 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/code-factory.h"
      6 
      7 #include "src/bootstrapper.h"
      8 #include "src/ic/ic.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 
     14 // static
     15 Callable CodeFactory::LoadIC(Isolate* isolate) {
     16   if (FLAG_tf_load_ic_stub) {
     17     LoadICTrampolineTFStub stub(isolate);
     18     return Callable(stub.GetCode(), LoadDescriptor(isolate));
     19   }
     20   LoadICTrampolineStub stub(isolate);
     21   return Callable(stub.GetCode(), LoadDescriptor(isolate));
     22 }
     23 
     24 // static
     25 Callable CodeFactory::ApiGetter(Isolate* isolate) {
     26   CallApiGetterStub stub(isolate);
     27   return Callable(stub.GetCode(), ApiGetterDescriptor(isolate));
     28 }
     29 
     30 // static
     31 Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate) {
     32   auto code = LoadIC::initialize_stub_in_optimized_code(isolate);
     33   return Callable(code, LoadWithVectorDescriptor(isolate));
     34 }
     35 
     36 // static
     37 Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) {
     38   LoadGlobalICTrampolineStub stub(isolate, LoadGlobalICState(typeof_mode));
     39   return Callable(stub.GetCode(), LoadGlobalDescriptor(isolate));
     40 }
     41 
     42 // static
     43 Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
     44                                                   TypeofMode typeof_mode) {
     45   auto code = LoadGlobalIC::initialize_stub_in_optimized_code(
     46       isolate, LoadGlobalICState(typeof_mode).GetExtraICState());
     47   return Callable(code, LoadGlobalWithVectorDescriptor(isolate));
     48 }
     49 
     50 // static
     51 Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
     52   KeyedLoadICTrampolineStub stub(isolate);
     53   return Callable(stub.GetCode(), LoadDescriptor(isolate));
     54 }
     55 
     56 
     57 // static
     58 Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
     59   auto code =
     60       KeyedLoadIC::initialize_stub_in_optimized_code(isolate, kNoExtraICState);
     61   return Callable(code, LoadWithVectorDescriptor(isolate));
     62 }
     63 
     64 
     65 // static
     66 Callable CodeFactory::CallIC(Isolate* isolate, int argc,
     67                              ConvertReceiverMode mode,
     68                              TailCallMode tail_call_mode) {
     69   CallICTrampolineStub stub(isolate, CallICState(argc, mode, tail_call_mode));
     70   return Callable(stub.GetCode(), CallFunctionWithFeedbackDescriptor(isolate));
     71 }
     72 
     73 
     74 // static
     75 Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc,
     76                                             ConvertReceiverMode mode,
     77                                             TailCallMode tail_call_mode) {
     78   return Callable(CallIC::initialize_stub_in_optimized_code(isolate, argc, mode,
     79                                                             tail_call_mode),
     80                   CallFunctionWithFeedbackAndVectorDescriptor(isolate));
     81 }
     82 
     83 
     84 // static
     85 Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
     86   VectorStoreICTrampolineStub stub(isolate, StoreICState(language_mode));
     87   return Callable(stub.GetCode(), VectorStoreICTrampolineDescriptor(isolate));
     88 }
     89 
     90 
     91 // static
     92 Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
     93                                              LanguageMode language_mode) {
     94   CallInterfaceDescriptor descriptor = VectorStoreICDescriptor(isolate);
     95   return Callable(
     96       StoreIC::initialize_stub_in_optimized_code(isolate, language_mode),
     97       descriptor);
     98 }
     99 
    100 
    101 // static
    102 Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
    103                                    LanguageMode language_mode) {
    104   VectorKeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode));
    105   return Callable(stub.GetCode(), VectorStoreICTrampolineDescriptor(isolate));
    106 }
    107 
    108 
    109 // static
    110 Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate,
    111                                                   LanguageMode language_mode) {
    112   CallInterfaceDescriptor descriptor = VectorStoreICDescriptor(isolate);
    113   return Callable(
    114       KeyedStoreIC::initialize_stub_in_optimized_code(isolate, language_mode),
    115       descriptor);
    116 }
    117 
    118 
    119 // static
    120 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
    121   Handle<Code> code = CompareIC::GetUninitialized(isolate, op);
    122   return Callable(code, CompareDescriptor(isolate));
    123 }
    124 
    125 
    126 // static
    127 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
    128   BinaryOpICStub stub(isolate, op);
    129   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    130 }
    131 
    132 
    133 // static
    134 Callable CodeFactory::InstanceOf(Isolate* isolate) {
    135   InstanceOfStub stub(isolate);
    136   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    137 }
    138 
    139 
    140 // static
    141 Callable CodeFactory::ToBoolean(Isolate* isolate) {
    142   ToBooleanStub stub(isolate);
    143   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    144 }
    145 
    146 
    147 // static
    148 Callable CodeFactory::ToNumber(Isolate* isolate) {
    149   return Callable(isolate->builtins()->ToNumber(),
    150                   TypeConversionDescriptor(isolate));
    151 }
    152 
    153 
    154 // static
    155 Callable CodeFactory::NonNumberToNumber(Isolate* isolate) {
    156   return Callable(isolate->builtins()->NonNumberToNumber(),
    157                   TypeConversionDescriptor(isolate));
    158 }
    159 
    160 // static
    161 Callable CodeFactory::StringToNumber(Isolate* isolate) {
    162   return Callable(isolate->builtins()->StringToNumber(),
    163                   TypeConversionDescriptor(isolate));
    164 }
    165 
    166 // static
    167 Callable CodeFactory::ToString(Isolate* isolate) {
    168   ToStringStub stub(isolate);
    169   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    170 }
    171 
    172 
    173 // static
    174 Callable CodeFactory::ToName(Isolate* isolate) {
    175   ToNameStub stub(isolate);
    176   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    177 }
    178 
    179 
    180 // static
    181 Callable CodeFactory::ToInteger(Isolate* isolate) {
    182   ToIntegerStub stub(isolate);
    183   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    184 }
    185 
    186 // static
    187 Callable CodeFactory::ToLength(Isolate* isolate) {
    188   ToLengthStub stub(isolate);
    189   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    190 }
    191 
    192 
    193 // static
    194 Callable CodeFactory::ToObject(Isolate* isolate) {
    195   ToObjectStub stub(isolate);
    196   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    197 }
    198 
    199 
    200 // static
    201 Callable CodeFactory::NumberToString(Isolate* isolate) {
    202   NumberToStringStub stub(isolate);
    203   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    204 }
    205 
    206 
    207 // static
    208 Callable CodeFactory::RegExpConstructResult(Isolate* isolate) {
    209   RegExpConstructResultStub stub(isolate);
    210   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    211 }
    212 
    213 
    214 // static
    215 Callable CodeFactory::RegExpExec(Isolate* isolate) {
    216   RegExpExecStub stub(isolate);
    217   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    218 }
    219 
    220 // static
    221 Callable CodeFactory::Add(Isolate* isolate) {
    222   AddStub stub(isolate);
    223   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    224 }
    225 
    226 // static
    227 Callable CodeFactory::Subtract(Isolate* isolate) {
    228   SubtractStub stub(isolate);
    229   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    230 }
    231 
    232 // static
    233 Callable CodeFactory::Multiply(Isolate* isolate) {
    234   MultiplyStub stub(isolate);
    235   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    236 }
    237 
    238 // static
    239 Callable CodeFactory::Divide(Isolate* isolate) {
    240   DivideStub stub(isolate);
    241   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    242 }
    243 
    244 // static
    245 Callable CodeFactory::Modulus(Isolate* isolate) {
    246   ModulusStub stub(isolate);
    247   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    248 }
    249 
    250 // static
    251 Callable CodeFactory::ShiftRight(Isolate* isolate) {
    252   ShiftRightStub stub(isolate);
    253   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    254 }
    255 
    256 // static
    257 Callable CodeFactory::ShiftRightLogical(Isolate* isolate) {
    258   ShiftRightLogicalStub stub(isolate);
    259   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    260 }
    261 
    262 // static
    263 Callable CodeFactory::ShiftLeft(Isolate* isolate) {
    264   ShiftLeftStub stub(isolate);
    265   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    266 }
    267 
    268 // static
    269 Callable CodeFactory::BitwiseAnd(Isolate* isolate) {
    270   BitwiseAndStub stub(isolate);
    271   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    272 }
    273 
    274 // static
    275 Callable CodeFactory::BitwiseOr(Isolate* isolate) {
    276   BitwiseOrStub stub(isolate);
    277   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    278 }
    279 
    280 // static
    281 Callable CodeFactory::BitwiseXor(Isolate* isolate) {
    282   BitwiseXorStub stub(isolate);
    283   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    284 }
    285 
    286 // static
    287 Callable CodeFactory::Inc(Isolate* isolate) {
    288   IncStub stub(isolate);
    289   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    290 }
    291 
    292 // static
    293 Callable CodeFactory::Dec(Isolate* isolate) {
    294   DecStub stub(isolate);
    295   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    296 }
    297 
    298 // static
    299 Callable CodeFactory::LessThan(Isolate* isolate) {
    300   LessThanStub stub(isolate);
    301   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    302 }
    303 
    304 // static
    305 Callable CodeFactory::LessThanOrEqual(Isolate* isolate) {
    306   LessThanOrEqualStub stub(isolate);
    307   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    308 }
    309 
    310 // static
    311 Callable CodeFactory::GreaterThan(Isolate* isolate) {
    312   GreaterThanStub stub(isolate);
    313   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    314 }
    315 
    316 // static
    317 Callable CodeFactory::GreaterThanOrEqual(Isolate* isolate) {
    318   GreaterThanOrEqualStub stub(isolate);
    319   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    320 }
    321 
    322 // static
    323 Callable CodeFactory::Equal(Isolate* isolate) {
    324   EqualStub stub(isolate);
    325   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    326 }
    327 
    328 // static
    329 Callable CodeFactory::NotEqual(Isolate* isolate) {
    330   NotEqualStub stub(isolate);
    331   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    332 }
    333 
    334 // static
    335 Callable CodeFactory::StrictEqual(Isolate* isolate) {
    336   StrictEqualStub stub(isolate);
    337   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    338 }
    339 
    340 // static
    341 Callable CodeFactory::StrictNotEqual(Isolate* isolate) {
    342   StrictNotEqualStub stub(isolate);
    343   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    344 }
    345 
    346 // static
    347 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
    348                                 PretenureFlag pretenure_flag) {
    349   StringAddStub stub(isolate, flags, pretenure_flag);
    350   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    351 }
    352 
    353 // static
    354 Callable CodeFactory::StringCompare(Isolate* isolate, Token::Value token) {
    355   switch (token) {
    356     case Token::EQ:
    357     case Token::EQ_STRICT:
    358       return StringEqual(isolate);
    359     case Token::NE:
    360     case Token::NE_STRICT:
    361       return StringNotEqual(isolate);
    362     case Token::LT:
    363       return StringLessThan(isolate);
    364     case Token::GT:
    365       return StringGreaterThan(isolate);
    366     case Token::LTE:
    367       return StringLessThanOrEqual(isolate);
    368     case Token::GTE:
    369       return StringGreaterThanOrEqual(isolate);
    370     default:
    371       break;
    372   }
    373   UNREACHABLE();
    374   return StringEqual(isolate);
    375 }
    376 
    377 // static
    378 Callable CodeFactory::StringEqual(Isolate* isolate) {
    379   StringEqualStub stub(isolate);
    380   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    381 }
    382 
    383 // static
    384 Callable CodeFactory::StringNotEqual(Isolate* isolate) {
    385   StringNotEqualStub stub(isolate);
    386   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    387 }
    388 
    389 // static
    390 Callable CodeFactory::StringLessThan(Isolate* isolate) {
    391   StringLessThanStub stub(isolate);
    392   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    393 }
    394 
    395 // static
    396 Callable CodeFactory::StringLessThanOrEqual(Isolate* isolate) {
    397   StringLessThanOrEqualStub stub(isolate);
    398   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    399 }
    400 
    401 // static
    402 Callable CodeFactory::StringGreaterThan(Isolate* isolate) {
    403   StringGreaterThanStub stub(isolate);
    404   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    405 }
    406 
    407 // static
    408 Callable CodeFactory::StringGreaterThanOrEqual(Isolate* isolate) {
    409   StringGreaterThanOrEqualStub stub(isolate);
    410   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    411 }
    412 
    413 // static
    414 Callable CodeFactory::SubString(Isolate* isolate) {
    415   SubStringStub stub(isolate);
    416   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    417 }
    418 
    419 
    420 // static
    421 Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
    422   return Callable(isolate->builtins()->ResumeGeneratorTrampoline(),
    423                   ResumeGeneratorDescriptor(isolate));
    424 }
    425 
    426 // static
    427 Callable CodeFactory::Typeof(Isolate* isolate) {
    428   TypeofStub stub(isolate);
    429   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    430 }
    431 
    432 
    433 // static
    434 Callable CodeFactory::FastCloneRegExp(Isolate* isolate) {
    435   FastCloneRegExpStub stub(isolate);
    436   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    437 }
    438 
    439 
    440 // static
    441 Callable CodeFactory::FastCloneShallowArray(Isolate* isolate) {
    442   // TODO(mstarzinger): Thread through AllocationSiteMode at some point.
    443   FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE);
    444   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    445 }
    446 
    447 
    448 // static
    449 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) {
    450   FastCloneShallowObjectStub stub(isolate, length);
    451   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    452 }
    453 
    454 
    455 // static
    456 Callable CodeFactory::FastNewContext(Isolate* isolate, int slot_count) {
    457   FastNewContextStub stub(isolate, slot_count);
    458   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    459 }
    460 
    461 
    462 // static
    463 Callable CodeFactory::FastNewClosure(Isolate* isolate,
    464                                      LanguageMode language_mode,
    465                                      FunctionKind kind) {
    466   FastNewClosureStub stub(isolate, language_mode, kind);
    467   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    468 }
    469 
    470 
    471 // static
    472 Callable CodeFactory::FastNewObject(Isolate* isolate) {
    473   FastNewObjectStub stub(isolate);
    474   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    475 }
    476 
    477 
    478 // static
    479 Callable CodeFactory::FastNewRestParameter(Isolate* isolate,
    480                                            bool skip_stub_frame) {
    481   FastNewRestParameterStub stub(isolate, skip_stub_frame);
    482   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    483 }
    484 
    485 
    486 // static
    487 Callable CodeFactory::FastNewSloppyArguments(Isolate* isolate,
    488                                              bool skip_stub_frame) {
    489   FastNewSloppyArgumentsStub stub(isolate, skip_stub_frame);
    490   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    491 }
    492 
    493 
    494 // static
    495 Callable CodeFactory::FastNewStrictArguments(Isolate* isolate,
    496                                              bool skip_stub_frame) {
    497   FastNewStrictArgumentsStub stub(isolate, skip_stub_frame);
    498   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    499 }
    500 
    501 
    502 // static
    503 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
    504   AllocateHeapNumberStub stub(isolate);
    505   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    506 }
    507 
    508 #define SIMD128_ALLOC(TYPE, Type, type, lane_count, lane_type)          \
    509   Callable CodeFactory::Allocate##Type(Isolate* isolate) {              \
    510     Allocate##Type##Stub stub(isolate);                                 \
    511     return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); \
    512   }
    513 SIMD128_TYPES(SIMD128_ALLOC)
    514 #undef SIMD128_ALLOC
    515 
    516 // static
    517 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
    518   return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(),
    519                   ArgumentAdaptorDescriptor(isolate));
    520 }
    521 
    522 
    523 // static
    524 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode,
    525                            TailCallMode tail_call_mode) {
    526   return Callable(isolate->builtins()->Call(mode, tail_call_mode),
    527                   CallTrampolineDescriptor(isolate));
    528 }
    529 
    530 
    531 // static
    532 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) {
    533   return Callable(isolate->builtins()->CallFunction(mode),
    534                   CallTrampolineDescriptor(isolate));
    535 }
    536 
    537 
    538 // static
    539 Callable CodeFactory::Construct(Isolate* isolate) {
    540   return Callable(isolate->builtins()->Construct(),
    541                   ConstructTrampolineDescriptor(isolate));
    542 }
    543 
    544 
    545 // static
    546 Callable CodeFactory::ConstructFunction(Isolate* isolate) {
    547   return Callable(isolate->builtins()->ConstructFunction(),
    548                   ConstructTrampolineDescriptor(isolate));
    549 }
    550 
    551 // static
    552 Callable CodeFactory::HasProperty(Isolate* isolate) {
    553   HasPropertyStub stub(isolate);
    554   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    555 }
    556 
    557 // static
    558 Callable CodeFactory::MathPow(Isolate* isolate) {
    559   MathPowStub stub(isolate, MathPowStub::ON_STACK);
    560   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
    561 }
    562 
    563 // static
    564 Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
    565                                                  TailCallMode tail_call_mode) {
    566   return Callable(
    567       isolate->builtins()->InterpreterPushArgsAndCall(tail_call_mode),
    568       InterpreterPushArgsAndCallDescriptor(isolate));
    569 }
    570 
    571 
    572 // static
    573 Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
    574   return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),
    575                   InterpreterPushArgsAndConstructDescriptor(isolate));
    576 }
    577 
    578 
    579 // static
    580 Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
    581   // Note: If we ever use fpregs in the interpreter then we will need to
    582   // save fpregs too.
    583   CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister);
    584   return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate));
    585 }
    586 
    587 }  // namespace internal
    588 }  // namespace v8
    589