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, TypeofMode typeof_mode, 16 LanguageMode language_mode) { 17 return Callable( 18 LoadIC::initialize_stub( 19 isolate, LoadICState(typeof_mode, language_mode).GetExtraICState()), 20 LoadDescriptor(isolate)); 21 } 22 23 24 // static 25 Callable CodeFactory::LoadICInOptimizedCode( 26 Isolate* isolate, TypeofMode typeof_mode, LanguageMode language_mode, 27 InlineCacheState initialization_state) { 28 auto code = LoadIC::initialize_stub_in_optimized_code( 29 isolate, LoadICState(typeof_mode, language_mode).GetExtraICState(), 30 initialization_state); 31 return Callable(code, LoadWithVectorDescriptor(isolate)); 32 } 33 34 35 // static 36 Callable CodeFactory::KeyedLoadIC(Isolate* isolate, 37 LanguageMode language_mode) { 38 ExtraICState state = is_strong(language_mode) ? LoadICState::kStrongModeState 39 : kNoExtraICState; 40 return Callable(KeyedLoadIC::initialize_stub(isolate, state), 41 LoadDescriptor(isolate)); 42 } 43 44 45 // static 46 Callable CodeFactory::KeyedLoadICInOptimizedCode( 47 Isolate* isolate, LanguageMode language_mode, 48 InlineCacheState initialization_state) { 49 ExtraICState state = is_strong(language_mode) ? LoadICState::kStrongModeState 50 : kNoExtraICState; 51 auto code = KeyedLoadIC::initialize_stub_in_optimized_code( 52 isolate, initialization_state, state); 53 if (initialization_state != MEGAMORPHIC) { 54 return Callable(code, LoadWithVectorDescriptor(isolate)); 55 } 56 return Callable(code, LoadDescriptor(isolate)); 57 } 58 59 60 // static 61 Callable CodeFactory::CallIC(Isolate* isolate, int argc, 62 ConvertReceiverMode mode) { 63 return Callable(CallIC::initialize_stub(isolate, argc, mode), 64 CallFunctionWithFeedbackDescriptor(isolate)); 65 } 66 67 68 // static 69 Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc, 70 ConvertReceiverMode mode) { 71 return Callable( 72 CallIC::initialize_stub_in_optimized_code(isolate, argc, mode), 73 CallFunctionWithFeedbackAndVectorDescriptor(isolate)); 74 } 75 76 77 // static 78 Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) { 79 return Callable( 80 StoreIC::initialize_stub(isolate, language_mode, UNINITIALIZED), 81 VectorStoreICTrampolineDescriptor(isolate)); 82 } 83 84 85 // static 86 Callable CodeFactory::StoreICInOptimizedCode( 87 Isolate* isolate, LanguageMode language_mode, 88 InlineCacheState initialization_state) { 89 CallInterfaceDescriptor descriptor = initialization_state != MEGAMORPHIC 90 ? VectorStoreICDescriptor(isolate) 91 : StoreDescriptor(isolate); 92 return Callable(StoreIC::initialize_stub_in_optimized_code( 93 isolate, language_mode, initialization_state), 94 descriptor); 95 } 96 97 98 // static 99 Callable CodeFactory::KeyedStoreIC(Isolate* isolate, 100 LanguageMode language_mode) { 101 return Callable( 102 KeyedStoreIC::initialize_stub(isolate, language_mode, UNINITIALIZED), 103 VectorStoreICTrampolineDescriptor(isolate)); 104 } 105 106 107 // static 108 Callable CodeFactory::KeyedStoreICInOptimizedCode( 109 Isolate* isolate, LanguageMode language_mode, 110 InlineCacheState initialization_state) { 111 CallInterfaceDescriptor descriptor = initialization_state != MEGAMORPHIC 112 ? VectorStoreICDescriptor(isolate) 113 : StoreDescriptor(isolate); 114 return Callable(KeyedStoreIC::initialize_stub_in_optimized_code( 115 isolate, language_mode, initialization_state), 116 descriptor); 117 } 118 119 120 // static 121 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op, 122 Strength strength) { 123 Handle<Code> code = CompareIC::GetUninitialized(isolate, op, strength); 124 return Callable(code, CompareDescriptor(isolate)); 125 } 126 127 128 // static 129 Callable CodeFactory::CompareNilIC(Isolate* isolate, NilValue nil_value) { 130 Handle<Code> code = CompareNilICStub::GetUninitialized(isolate, nil_value); 131 return Callable(code, CompareNilDescriptor(isolate)); 132 } 133 134 135 // static 136 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op, 137 Strength strength) { 138 BinaryOpICStub stub(isolate, op, strength); 139 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 140 } 141 142 143 // static 144 Callable CodeFactory::InstanceOf(Isolate* isolate) { 145 InstanceOfStub stub(isolate); 146 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 147 } 148 149 150 // static 151 Callable CodeFactory::ToBoolean(Isolate* isolate) { 152 Handle<Code> code = ToBooleanStub::GetUninitialized(isolate); 153 return Callable(code, ToBooleanDescriptor(isolate)); 154 } 155 156 157 // static 158 Callable CodeFactory::ToNumber(Isolate* isolate) { 159 ToNumberStub stub(isolate); 160 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 161 } 162 163 164 // static 165 Callable CodeFactory::ToString(Isolate* isolate) { 166 ToStringStub stub(isolate); 167 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 168 } 169 170 171 // static 172 Callable CodeFactory::ToLength(Isolate* isolate) { 173 ToLengthStub stub(isolate); 174 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 175 } 176 177 178 // static 179 Callable CodeFactory::ToObject(Isolate* isolate) { 180 ToObjectStub stub(isolate); 181 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 182 } 183 184 185 // static 186 Callable CodeFactory::NumberToString(Isolate* isolate) { 187 NumberToStringStub stub(isolate); 188 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 189 } 190 191 192 // static 193 Callable CodeFactory::RegExpConstructResult(Isolate* isolate) { 194 RegExpConstructResultStub stub(isolate); 195 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 196 } 197 198 199 // static 200 Callable CodeFactory::RegExpExec(Isolate* isolate) { 201 RegExpExecStub stub(isolate); 202 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 203 } 204 205 206 // static 207 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags, 208 PretenureFlag pretenure_flag) { 209 StringAddStub stub(isolate, flags, pretenure_flag); 210 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 211 } 212 213 214 // static 215 Callable CodeFactory::StringCompare(Isolate* isolate) { 216 StringCompareStub stub(isolate); 217 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 218 } 219 220 221 // static 222 Callable CodeFactory::SubString(Isolate* isolate) { 223 SubStringStub stub(isolate); 224 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 225 } 226 227 228 // static 229 Callable CodeFactory::Typeof(Isolate* isolate) { 230 TypeofStub stub(isolate); 231 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 232 } 233 234 235 // static 236 Callable CodeFactory::FastCloneRegExp(Isolate* isolate) { 237 FastCloneRegExpStub stub(isolate); 238 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 239 } 240 241 242 // static 243 Callable CodeFactory::FastCloneShallowArray(Isolate* isolate) { 244 // TODO(mstarzinger): Thread through AllocationSiteMode at some point. 245 FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE); 246 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 247 } 248 249 250 // static 251 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) { 252 FastCloneShallowObjectStub stub(isolate, length); 253 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 254 } 255 256 257 // static 258 Callable CodeFactory::FastNewContext(Isolate* isolate, int slot_count) { 259 FastNewContextStub stub(isolate, slot_count); 260 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 261 } 262 263 264 // static 265 Callable CodeFactory::FastNewClosure(Isolate* isolate, 266 LanguageMode language_mode, 267 FunctionKind kind) { 268 FastNewClosureStub stub(isolate, language_mode, kind); 269 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 270 } 271 272 273 // static 274 Callable CodeFactory::ArgumentsAccess(Isolate* isolate, 275 bool is_unmapped_arguments, 276 bool has_duplicate_parameters) { 277 ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType( 278 is_unmapped_arguments, has_duplicate_parameters); 279 ArgumentsAccessStub stub(isolate, type); 280 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 281 } 282 283 284 // static 285 Callable CodeFactory::RestArgumentsAccess(Isolate* isolate) { 286 RestParamAccessStub stub(isolate); 287 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 288 } 289 290 291 // static 292 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) { 293 AllocateHeapNumberStub stub(isolate); 294 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 295 } 296 297 298 // static 299 Callable CodeFactory::AllocateMutableHeapNumber(Isolate* isolate) { 300 AllocateMutableHeapNumberStub stub(isolate); 301 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 302 } 303 304 305 // static 306 Callable CodeFactory::AllocateInNewSpace(Isolate* isolate) { 307 AllocateInNewSpaceStub stub(isolate); 308 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 309 } 310 311 312 // static 313 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) { 314 return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(), 315 ArgumentAdaptorDescriptor(isolate)); 316 } 317 318 319 // static 320 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode) { 321 return Callable(isolate->builtins()->Call(mode), 322 CallTrampolineDescriptor(isolate)); 323 } 324 325 326 // static 327 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) { 328 return Callable(isolate->builtins()->CallFunction(mode), 329 CallTrampolineDescriptor(isolate)); 330 } 331 332 333 // static 334 Callable CodeFactory::Construct(Isolate* isolate) { 335 return Callable(isolate->builtins()->Construct(), 336 ConstructTrampolineDescriptor(isolate)); 337 } 338 339 340 // static 341 Callable CodeFactory::ConstructFunction(Isolate* isolate) { 342 return Callable(isolate->builtins()->ConstructFunction(), 343 ConstructTrampolineDescriptor(isolate)); 344 } 345 346 347 // static 348 Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate) { 349 return Callable(isolate->builtins()->InterpreterPushArgsAndCall(), 350 InterpreterPushArgsAndCallDescriptor(isolate)); 351 } 352 353 354 // static 355 Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) { 356 return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(), 357 InterpreterPushArgsAndConstructDescriptor(isolate)); 358 } 359 360 361 // static 362 Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) { 363 // Note: If we ever use fpregs in the interpreter then we will need to 364 // save fpregs too. 365 CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister); 366 return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate)); 367 } 368 369 } // namespace internal 370 } // namespace v8 371