1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_BUILTINS_H_ 29 #define V8_BUILTINS_H_ 30 31 namespace v8 { 32 namespace internal { 33 34 // Specifies extra arguments required by a C++ builtin. 35 enum BuiltinExtraArguments { 36 NO_EXTRA_ARGUMENTS = 0, 37 NEEDS_CALLED_FUNCTION = 1 38 }; 39 40 41 #define CODE_AGE_LIST_WITH_ARG(V, A) \ 42 V(Quadragenarian, A) \ 43 V(Quinquagenarian, A) \ 44 V(Sexagenarian, A) \ 45 V(Septuagenarian, A) \ 46 V(Octogenarian, A) 47 48 #define CODE_AGE_LIST_IGNORE_ARG(X, V) V(X) 49 50 #define CODE_AGE_LIST(V) \ 51 CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V) 52 53 #define DECLARE_CODE_AGE_BUILTIN(C, V) \ 54 V(Make##C##CodeYoungAgainOddMarking, BUILTIN, \ 55 UNINITIALIZED, Code::kNoExtraICState) \ 56 V(Make##C##CodeYoungAgainEvenMarking, BUILTIN, \ 57 UNINITIALIZED, Code::kNoExtraICState) 58 59 60 // Define list of builtins implemented in C++. 61 #define BUILTIN_LIST_C(V) \ 62 V(Illegal, NO_EXTRA_ARGUMENTS) \ 63 \ 64 V(EmptyFunction, NO_EXTRA_ARGUMENTS) \ 65 \ 66 V(InternalArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \ 67 V(ArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \ 68 \ 69 V(ArrayPush, NO_EXTRA_ARGUMENTS) \ 70 V(ArrayPop, NO_EXTRA_ARGUMENTS) \ 71 V(ArrayShift, NO_EXTRA_ARGUMENTS) \ 72 V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \ 73 V(ArraySlice, NO_EXTRA_ARGUMENTS) \ 74 V(ArraySplice, NO_EXTRA_ARGUMENTS) \ 75 V(ArrayConcat, NO_EXTRA_ARGUMENTS) \ 76 \ 77 V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ 78 V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ 79 V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ 80 V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \ 81 \ 82 V(StrictModePoisonPill, NO_EXTRA_ARGUMENTS) 83 84 // Define list of builtins implemented in assembly. 85 #define BUILTIN_LIST_A(V) \ 86 V(ArgumentsAdaptorTrampoline, BUILTIN, UNINITIALIZED, \ 87 Code::kNoExtraICState) \ 88 V(InRecompileQueue, BUILTIN, UNINITIALIZED, \ 89 Code::kNoExtraICState) \ 90 V(InstallRecompiledCode, BUILTIN, UNINITIALIZED, \ 91 Code::kNoExtraICState) \ 92 V(JSConstructStubCountdown, BUILTIN, UNINITIALIZED, \ 93 Code::kNoExtraICState) \ 94 V(JSConstructStubGeneric, BUILTIN, UNINITIALIZED, \ 95 Code::kNoExtraICState) \ 96 V(JSConstructStubApi, BUILTIN, UNINITIALIZED, \ 97 Code::kNoExtraICState) \ 98 V(JSEntryTrampoline, BUILTIN, UNINITIALIZED, \ 99 Code::kNoExtraICState) \ 100 V(JSConstructEntryTrampoline, BUILTIN, UNINITIALIZED, \ 101 Code::kNoExtraICState) \ 102 V(LazyCompile, BUILTIN, UNINITIALIZED, \ 103 Code::kNoExtraICState) \ 104 V(LazyRecompile, BUILTIN, UNINITIALIZED, \ 105 Code::kNoExtraICState) \ 106 V(ParallelRecompile, BUILTIN, UNINITIALIZED, \ 107 Code::kNoExtraICState) \ 108 V(NotifyDeoptimized, BUILTIN, UNINITIALIZED, \ 109 Code::kNoExtraICState) \ 110 V(NotifySoftDeoptimized, BUILTIN, UNINITIALIZED, \ 111 Code::kNoExtraICState) \ 112 V(NotifyLazyDeoptimized, BUILTIN, UNINITIALIZED, \ 113 Code::kNoExtraICState) \ 114 V(NotifyStubFailure, BUILTIN, UNINITIALIZED, \ 115 Code::kNoExtraICState) \ 116 V(NotifyOSR, BUILTIN, UNINITIALIZED, \ 117 Code::kNoExtraICState) \ 118 \ 119 V(LoadIC_Miss, BUILTIN, UNINITIALIZED, \ 120 Code::kNoExtraICState) \ 121 V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, \ 122 Code::kNoExtraICState) \ 123 V(KeyedLoadIC_MissForceGeneric, BUILTIN, UNINITIALIZED, \ 124 Code::kNoExtraICState) \ 125 V(KeyedLoadIC_Slow, BUILTIN, UNINITIALIZED, \ 126 Code::kNoExtraICState) \ 127 V(StoreIC_Miss, BUILTIN, UNINITIALIZED, \ 128 Code::kNoExtraICState) \ 129 V(StoreIC_Slow, BUILTIN, UNINITIALIZED, \ 130 Code::kNoExtraICState) \ 131 V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED, \ 132 Code::kNoExtraICState) \ 133 V(KeyedStoreIC_MissForceGeneric, BUILTIN, UNINITIALIZED, \ 134 Code::kNoExtraICState) \ 135 V(KeyedStoreIC_Slow, BUILTIN, UNINITIALIZED, \ 136 Code::kNoExtraICState) \ 137 V(LoadIC_Initialize, LOAD_IC, UNINITIALIZED, \ 138 Code::kNoExtraICState) \ 139 V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC, \ 140 Code::kNoExtraICState) \ 141 V(LoadIC_Normal, LOAD_IC, MONOMORPHIC, \ 142 Code::kNoExtraICState) \ 143 V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \ 144 Code::kNoExtraICState) \ 145 V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, \ 146 Code::kNoExtraICState) \ 147 V(LoadIC_Slow, LOAD_IC, GENERIC, \ 148 Code::kNoExtraICState) \ 149 \ 150 V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, \ 151 Code::kNoExtraICState) \ 152 V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC, \ 153 Code::kNoExtraICState) \ 154 V(KeyedLoadIC_Generic, KEYED_LOAD_IC, GENERIC, \ 155 Code::kNoExtraICState) \ 156 V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC, \ 157 Code::kNoExtraICState) \ 158 V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MONOMORPHIC, \ 159 Code::kNoExtraICState) \ 160 V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, MONOMORPHIC, \ 161 Code::kNoExtraICState) \ 162 \ 163 V(StoreIC_Initialize, STORE_IC, UNINITIALIZED, \ 164 Code::kNoExtraICState) \ 165 V(StoreIC_Normal, STORE_IC, MONOMORPHIC, \ 166 Code::kNoExtraICState) \ 167 V(StoreIC_Megamorphic, STORE_IC, MEGAMORPHIC, \ 168 Code::kNoExtraICState) \ 169 V(StoreIC_Generic, STORE_IC, GENERIC, \ 170 Code::kNoExtraICState) \ 171 V(StoreIC_Generic_Strict, STORE_IC, GENERIC, \ 172 kStrictMode) \ 173 V(StoreIC_GlobalProxy, STORE_IC, GENERIC, \ 174 Code::kNoExtraICState) \ 175 V(StoreIC_Initialize_Strict, STORE_IC, UNINITIALIZED, \ 176 kStrictMode) \ 177 V(StoreIC_Normal_Strict, STORE_IC, MONOMORPHIC, \ 178 kStrictMode) \ 179 V(StoreIC_Megamorphic_Strict, STORE_IC, MEGAMORPHIC, \ 180 kStrictMode) \ 181 V(StoreIC_GlobalProxy_Strict, STORE_IC, GENERIC, \ 182 kStrictMode) \ 183 V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, \ 184 kStrictMode) \ 185 \ 186 V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, \ 187 Code::kNoExtraICState) \ 188 V(KeyedStoreIC_Generic, KEYED_STORE_IC, GENERIC, \ 189 Code::kNoExtraICState) \ 190 \ 191 V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED, \ 192 kStrictMode) \ 193 V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, GENERIC, \ 194 kStrictMode) \ 195 V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, MONOMORPHIC, \ 196 Code::kNoExtraICState) \ 197 \ 198 /* Uses KeyedLoadIC_Initialize; must be after in list. */ \ 199 V(FunctionCall, BUILTIN, UNINITIALIZED, \ 200 Code::kNoExtraICState) \ 201 V(FunctionApply, BUILTIN, UNINITIALIZED, \ 202 Code::kNoExtraICState) \ 203 \ 204 V(InternalArrayCode, BUILTIN, UNINITIALIZED, \ 205 Code::kNoExtraICState) \ 206 V(ArrayCode, BUILTIN, UNINITIALIZED, \ 207 Code::kNoExtraICState) \ 208 \ 209 V(StringConstructCode, BUILTIN, UNINITIALIZED, \ 210 Code::kNoExtraICState) \ 211 \ 212 V(OnStackReplacement, BUILTIN, UNINITIALIZED, \ 213 Code::kNoExtraICState) \ 214 CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V) 215 216 #ifdef ENABLE_DEBUGGER_SUPPORT 217 // Define list of builtins used by the debugger implemented in assembly. 218 #define BUILTIN_LIST_DEBUG_A(V) \ 219 V(Return_DebugBreak, BUILTIN, DEBUG_STUB, \ 220 DEBUG_BREAK) \ 221 V(CallFunctionStub_DebugBreak, BUILTIN, DEBUG_STUB, \ 222 DEBUG_BREAK) \ 223 V(CallFunctionStub_Recording_DebugBreak, BUILTIN, DEBUG_STUB, \ 224 DEBUG_BREAK) \ 225 V(CallConstructStub_DebugBreak, BUILTIN, DEBUG_STUB, \ 226 DEBUG_BREAK) \ 227 V(CallConstructStub_Recording_DebugBreak, BUILTIN, DEBUG_STUB, \ 228 DEBUG_BREAK) \ 229 V(LoadIC_DebugBreak, LOAD_IC, DEBUG_STUB, \ 230 DEBUG_BREAK) \ 231 V(KeyedLoadIC_DebugBreak, KEYED_LOAD_IC, DEBUG_STUB, \ 232 DEBUG_BREAK) \ 233 V(StoreIC_DebugBreak, STORE_IC, DEBUG_STUB, \ 234 DEBUG_BREAK) \ 235 V(KeyedStoreIC_DebugBreak, KEYED_STORE_IC, DEBUG_STUB, \ 236 DEBUG_BREAK) \ 237 V(CompareNilIC_DebugBreak, COMPARE_NIL_IC, DEBUG_STUB, \ 238 DEBUG_BREAK) \ 239 V(Slot_DebugBreak, BUILTIN, DEBUG_STUB, \ 240 DEBUG_BREAK) \ 241 V(PlainReturn_LiveEdit, BUILTIN, DEBUG_STUB, \ 242 DEBUG_BREAK) \ 243 V(FrameDropper_LiveEdit, BUILTIN, DEBUG_STUB, \ 244 DEBUG_BREAK) 245 #else 246 #define BUILTIN_LIST_DEBUG_A(V) 247 #endif 248 249 // Define list of builtins implemented in JavaScript. 250 #define BUILTINS_LIST_JS(V) \ 251 V(EQUALS, 1) \ 252 V(STRICT_EQUALS, 1) \ 253 V(COMPARE, 2) \ 254 V(ADD, 1) \ 255 V(SUB, 1) \ 256 V(MUL, 1) \ 257 V(DIV, 1) \ 258 V(MOD, 1) \ 259 V(BIT_OR, 1) \ 260 V(BIT_AND, 1) \ 261 V(BIT_XOR, 1) \ 262 V(SHL, 1) \ 263 V(SAR, 1) \ 264 V(SHR, 1) \ 265 V(DELETE, 2) \ 266 V(IN, 1) \ 267 V(INSTANCE_OF, 1) \ 268 V(FILTER_KEY, 1) \ 269 V(CALL_NON_FUNCTION, 0) \ 270 V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \ 271 V(CALL_FUNCTION_PROXY, 1) \ 272 V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \ 273 V(TO_OBJECT, 0) \ 274 V(TO_NUMBER, 0) \ 275 V(TO_STRING, 0) \ 276 V(STRING_ADD_LEFT, 1) \ 277 V(STRING_ADD_RIGHT, 1) \ 278 V(APPLY_PREPARE, 1) \ 279 V(APPLY_OVERFLOW, 1) 280 281 class BuiltinFunctionTable; 282 class ObjectVisitor; 283 284 285 class Builtins { 286 public: 287 ~Builtins(); 288 289 // Generate all builtin code objects. Should be called once during 290 // isolate initialization. 291 void SetUp(bool create_heap_objects); 292 void TearDown(); 293 294 // Garbage collection support. 295 void IterateBuiltins(ObjectVisitor* v); 296 297 // Disassembler support. 298 const char* Lookup(byte* pc); 299 300 enum Name { 301 #define DEF_ENUM_C(name, ignore) k##name, 302 #define DEF_ENUM_A(name, kind, state, extra) k##name, 303 BUILTIN_LIST_C(DEF_ENUM_C) 304 BUILTIN_LIST_A(DEF_ENUM_A) 305 BUILTIN_LIST_DEBUG_A(DEF_ENUM_A) 306 #undef DEF_ENUM_C 307 #undef DEF_ENUM_A 308 builtin_count 309 }; 310 311 enum CFunctionId { 312 #define DEF_ENUM_C(name, ignore) c_##name, 313 BUILTIN_LIST_C(DEF_ENUM_C) 314 #undef DEF_ENUM_C 315 cfunction_count 316 }; 317 318 enum JavaScript { 319 #define DEF_ENUM(name, ignore) name, 320 BUILTINS_LIST_JS(DEF_ENUM) 321 #undef DEF_ENUM 322 id_count 323 }; 324 325 #define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name(); 326 #define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ 327 Handle<Code> name(); 328 BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C) 329 BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A) 330 BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A) 331 #undef DECLARE_BUILTIN_ACCESSOR_C 332 #undef DECLARE_BUILTIN_ACCESSOR_A 333 334 Code* builtin(Name name) { 335 // Code::cast cannot be used here since we access builtins 336 // during the marking phase of mark sweep. See IC::Clear. 337 return reinterpret_cast<Code*>(builtins_[name]); 338 } 339 340 Address builtin_address(Name name) { 341 return reinterpret_cast<Address>(&builtins_[name]); 342 } 343 344 static Address c_function_address(CFunctionId id) { 345 return c_functions_[id]; 346 } 347 348 static const char* GetName(JavaScript id) { return javascript_names_[id]; } 349 static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; } 350 Handle<Code> GetCode(JavaScript id, bool* resolved); 351 static int NumberOfJavaScriptBuiltins() { return id_count; } 352 353 bool is_initialized() const { return initialized_; } 354 355 private: 356 Builtins(); 357 358 // The external C++ functions called from the code. 359 static Address const c_functions_[cfunction_count]; 360 361 // Note: These are always Code objects, but to conform with 362 // IterateBuiltins() above which assumes Object**'s for the callback 363 // function f, we use an Object* array here. 364 Object* builtins_[builtin_count]; 365 const char* names_[builtin_count]; 366 static const char* const javascript_names_[id_count]; 367 static int const javascript_argc_[id_count]; 368 369 static void Generate_Adaptor(MacroAssembler* masm, 370 CFunctionId id, 371 BuiltinExtraArguments extra_args); 372 static void Generate_InRecompileQueue(MacroAssembler* masm); 373 static void Generate_InstallRecompiledCode(MacroAssembler* masm); 374 static void Generate_ParallelRecompile(MacroAssembler* masm); 375 static void Generate_JSConstructStubCountdown(MacroAssembler* masm); 376 static void Generate_JSConstructStubGeneric(MacroAssembler* masm); 377 static void Generate_JSConstructStubApi(MacroAssembler* masm); 378 static void Generate_JSEntryTrampoline(MacroAssembler* masm); 379 static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm); 380 static void Generate_LazyCompile(MacroAssembler* masm); 381 static void Generate_LazyRecompile(MacroAssembler* masm); 382 static void Generate_NotifyDeoptimized(MacroAssembler* masm); 383 static void Generate_NotifySoftDeoptimized(MacroAssembler* masm); 384 static void Generate_NotifyLazyDeoptimized(MacroAssembler* masm); 385 static void Generate_NotifyOSR(MacroAssembler* masm); 386 static void Generate_NotifyStubFailure(MacroAssembler* masm); 387 static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm); 388 389 static void Generate_FunctionCall(MacroAssembler* masm); 390 static void Generate_FunctionApply(MacroAssembler* masm); 391 392 static void Generate_InternalArrayCode(MacroAssembler* masm); 393 static void Generate_ArrayCode(MacroAssembler* masm); 394 395 static void Generate_StringConstructCode(MacroAssembler* masm); 396 static void Generate_OnStackReplacement(MacroAssembler* masm); 397 398 #define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \ 399 static void Generate_Make##C##CodeYoungAgainEvenMarking( \ 400 MacroAssembler* masm); \ 401 static void Generate_Make##C##CodeYoungAgainOddMarking( \ 402 MacroAssembler* masm); 403 CODE_AGE_LIST(DECLARE_CODE_AGE_BUILTIN_GENERATOR) 404 #undef DECLARE_CODE_AGE_BUILTIN_GENERATOR 405 406 static void InitBuiltinFunctionTable(); 407 408 bool initialized_; 409 410 friend class BuiltinFunctionTable; 411 friend class Isolate; 412 413 DISALLOW_COPY_AND_ASSIGN(Builtins); 414 }; 415 416 } } // namespace v8::internal 417 418 #endif // V8_BUILTINS_H_ 419