builtins.h revision c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9
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 31namespace v8 { 32namespace internal { 33 34// Specifies extra arguments required by a C++ builtin. 35enum BuiltinExtraArguments { 36 NO_EXTRA_ARGUMENTS = 0, 37 NEEDS_CALLED_FUNCTION = 1 38}; 39 40 41// Define list of builtins implemented in C++. 42#define BUILTIN_LIST_C(V) \ 43 V(Illegal, NO_EXTRA_ARGUMENTS) \ 44 \ 45 V(EmptyFunction, NO_EXTRA_ARGUMENTS) \ 46 \ 47 V(InternalArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \ 48 V(ArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \ 49 \ 50 V(ArrayPush, NO_EXTRA_ARGUMENTS) \ 51 V(ArrayPop, NO_EXTRA_ARGUMENTS) \ 52 V(ArrayShift, NO_EXTRA_ARGUMENTS) \ 53 V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \ 54 V(ArraySlice, NO_EXTRA_ARGUMENTS) \ 55 V(ArraySplice, NO_EXTRA_ARGUMENTS) \ 56 V(ArrayConcat, NO_EXTRA_ARGUMENTS) \ 57 \ 58 V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ 59 V(FastHandleApiCall, NO_EXTRA_ARGUMENTS) \ 60 V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ 61 V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ 62 V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \ 63 \ 64 V(StrictModePoisonPill, NO_EXTRA_ARGUMENTS) 65 66// Define list of builtins implemented in assembly. 67#define BUILTIN_LIST_A(V) \ 68 V(ArgumentsAdaptorTrampoline, BUILTIN, UNINITIALIZED, \ 69 Code::kNoExtraICState) \ 70 V(JSConstructCall, BUILTIN, UNINITIALIZED, \ 71 Code::kNoExtraICState) \ 72 V(JSConstructStubCountdown, BUILTIN, UNINITIALIZED, \ 73 Code::kNoExtraICState) \ 74 V(JSConstructStubGeneric, BUILTIN, UNINITIALIZED, \ 75 Code::kNoExtraICState) \ 76 V(JSConstructStubApi, BUILTIN, UNINITIALIZED, \ 77 Code::kNoExtraICState) \ 78 V(JSEntryTrampoline, BUILTIN, UNINITIALIZED, \ 79 Code::kNoExtraICState) \ 80 V(JSConstructEntryTrampoline, BUILTIN, UNINITIALIZED, \ 81 Code::kNoExtraICState) \ 82 V(LazyCompile, BUILTIN, UNINITIALIZED, \ 83 Code::kNoExtraICState) \ 84 V(LazyRecompile, BUILTIN, UNINITIALIZED, \ 85 Code::kNoExtraICState) \ 86 V(NotifyDeoptimized, BUILTIN, UNINITIALIZED, \ 87 Code::kNoExtraICState) \ 88 V(NotifyLazyDeoptimized, BUILTIN, UNINITIALIZED, \ 89 Code::kNoExtraICState) \ 90 V(NotifyOSR, BUILTIN, UNINITIALIZED, \ 91 Code::kNoExtraICState) \ 92 \ 93 V(LoadIC_Miss, BUILTIN, UNINITIALIZED, \ 94 Code::kNoExtraICState) \ 95 V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, \ 96 Code::kNoExtraICState) \ 97 V(KeyedLoadIC_MissForceGeneric, BUILTIN, UNINITIALIZED, \ 98 Code::kNoExtraICState) \ 99 V(KeyedLoadIC_Slow, BUILTIN, UNINITIALIZED, \ 100 Code::kNoExtraICState) \ 101 V(StoreIC_Miss, BUILTIN, UNINITIALIZED, \ 102 Code::kNoExtraICState) \ 103 V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED, \ 104 Code::kNoExtraICState) \ 105 V(KeyedStoreIC_MissForceGeneric, BUILTIN, UNINITIALIZED, \ 106 Code::kNoExtraICState) \ 107 V(KeyedStoreIC_Slow, BUILTIN, UNINITIALIZED, \ 108 Code::kNoExtraICState) \ 109 V(LoadIC_Initialize, LOAD_IC, UNINITIALIZED, \ 110 Code::kNoExtraICState) \ 111 V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC, \ 112 Code::kNoExtraICState) \ 113 V(LoadIC_Normal, LOAD_IC, MONOMORPHIC, \ 114 Code::kNoExtraICState) \ 115 V(LoadIC_ArrayLength, LOAD_IC, MONOMORPHIC, \ 116 Code::kNoExtraICState) \ 117 V(LoadIC_StringLength, LOAD_IC, MONOMORPHIC, \ 118 Code::kNoExtraICState) \ 119 V(LoadIC_StringWrapperLength, LOAD_IC, MONOMORPHIC, \ 120 Code::kNoExtraICState) \ 121 V(LoadIC_FunctionPrototype, LOAD_IC, MONOMORPHIC, \ 122 Code::kNoExtraICState) \ 123 V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC, \ 124 Code::kNoExtraICState) \ 125 \ 126 V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, \ 127 Code::kNoExtraICState) \ 128 V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC, \ 129 Code::kNoExtraICState) \ 130 V(KeyedLoadIC_Generic, KEYED_LOAD_IC, MEGAMORPHIC, \ 131 Code::kNoExtraICState) \ 132 V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC, \ 133 Code::kNoExtraICState) \ 134 V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MEGAMORPHIC, \ 135 Code::kNoExtraICState) \ 136 V(KeyedLoadIC_NonStrictArguments, KEYED_LOAD_IC, MEGAMORPHIC, \ 137 Code::kNoExtraICState) \ 138 \ 139 V(StoreIC_Initialize, STORE_IC, UNINITIALIZED, \ 140 Code::kNoExtraICState) \ 141 V(StoreIC_ArrayLength, STORE_IC, MONOMORPHIC, \ 142 Code::kNoExtraICState) \ 143 V(StoreIC_Normal, STORE_IC, MONOMORPHIC, \ 144 Code::kNoExtraICState) \ 145 V(StoreIC_Megamorphic, STORE_IC, MEGAMORPHIC, \ 146 Code::kNoExtraICState) \ 147 V(StoreIC_GlobalProxy, STORE_IC, MEGAMORPHIC, \ 148 Code::kNoExtraICState) \ 149 V(StoreIC_Initialize_Strict, STORE_IC, UNINITIALIZED, \ 150 kStrictMode) \ 151 V(StoreIC_ArrayLength_Strict, STORE_IC, MONOMORPHIC, \ 152 kStrictMode) \ 153 V(StoreIC_Normal_Strict, STORE_IC, MONOMORPHIC, \ 154 kStrictMode) \ 155 V(StoreIC_Megamorphic_Strict, STORE_IC, MEGAMORPHIC, \ 156 kStrictMode) \ 157 V(StoreIC_GlobalProxy_Strict, STORE_IC, MEGAMORPHIC, \ 158 kStrictMode) \ 159 \ 160 V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, \ 161 Code::kNoExtraICState) \ 162 V(KeyedStoreIC_Generic, KEYED_STORE_IC, MEGAMORPHIC, \ 163 Code::kNoExtraICState) \ 164 \ 165 V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED, \ 166 kStrictMode) \ 167 V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, MEGAMORPHIC, \ 168 kStrictMode) \ 169 V(KeyedStoreIC_NonStrictArguments, KEYED_STORE_IC, MEGAMORPHIC, \ 170 Code::kNoExtraICState) \ 171 V(TransitionElementsSmiToDouble, BUILTIN, UNINITIALIZED, \ 172 Code::kNoExtraICState) \ 173 V(TransitionElementsDoubleToObject, BUILTIN, UNINITIALIZED, \ 174 Code::kNoExtraICState) \ 175 \ 176 /* Uses KeyedLoadIC_Initialize; must be after in list. */ \ 177 V(FunctionCall, BUILTIN, UNINITIALIZED, \ 178 Code::kNoExtraICState) \ 179 V(FunctionApply, BUILTIN, UNINITIALIZED, \ 180 Code::kNoExtraICState) \ 181 \ 182 V(InternalArrayCode, BUILTIN, UNINITIALIZED, \ 183 Code::kNoExtraICState) \ 184 V(ArrayCode, BUILTIN, UNINITIALIZED, \ 185 Code::kNoExtraICState) \ 186 V(ArrayConstructCode, BUILTIN, UNINITIALIZED, \ 187 Code::kNoExtraICState) \ 188 \ 189 V(StringConstructCode, BUILTIN, UNINITIALIZED, \ 190 Code::kNoExtraICState) \ 191 \ 192 V(OnStackReplacement, BUILTIN, UNINITIALIZED, \ 193 Code::kNoExtraICState) 194 195 196#ifdef ENABLE_DEBUGGER_SUPPORT 197// Define list of builtins used by the debugger implemented in assembly. 198#define BUILTIN_LIST_DEBUG_A(V) \ 199 V(Return_DebugBreak, BUILTIN, DEBUG_BREAK, \ 200 Code::kNoExtraICState) \ 201 V(ConstructCall_DebugBreak, BUILTIN, DEBUG_BREAK, \ 202 Code::kNoExtraICState) \ 203 V(CallFunctionStub_DebugBreak, BUILTIN, DEBUG_BREAK, \ 204 Code::kNoExtraICState) \ 205 V(LoadIC_DebugBreak, LOAD_IC, DEBUG_BREAK, \ 206 Code::kNoExtraICState) \ 207 V(KeyedLoadIC_DebugBreak, KEYED_LOAD_IC, DEBUG_BREAK, \ 208 Code::kNoExtraICState) \ 209 V(StoreIC_DebugBreak, STORE_IC, DEBUG_BREAK, \ 210 Code::kNoExtraICState) \ 211 V(KeyedStoreIC_DebugBreak, KEYED_STORE_IC, DEBUG_BREAK, \ 212 Code::kNoExtraICState) \ 213 V(Slot_DebugBreak, BUILTIN, DEBUG_BREAK, \ 214 Code::kNoExtraICState) \ 215 V(PlainReturn_LiveEdit, BUILTIN, DEBUG_BREAK, \ 216 Code::kNoExtraICState) \ 217 V(FrameDropper_LiveEdit, BUILTIN, DEBUG_BREAK, \ 218 Code::kNoExtraICState) 219#else 220#define BUILTIN_LIST_DEBUG_A(V) 221#endif 222 223// Define list of builtins implemented in JavaScript. 224#define BUILTINS_LIST_JS(V) \ 225 V(EQUALS, 1) \ 226 V(STRICT_EQUALS, 1) \ 227 V(COMPARE, 2) \ 228 V(ADD, 1) \ 229 V(SUB, 1) \ 230 V(MUL, 1) \ 231 V(DIV, 1) \ 232 V(MOD, 1) \ 233 V(BIT_OR, 1) \ 234 V(BIT_AND, 1) \ 235 V(BIT_XOR, 1) \ 236 V(UNARY_MINUS, 0) \ 237 V(BIT_NOT, 0) \ 238 V(SHL, 1) \ 239 V(SAR, 1) \ 240 V(SHR, 1) \ 241 V(DELETE, 2) \ 242 V(IN, 1) \ 243 V(INSTANCE_OF, 1) \ 244 V(FILTER_KEY, 1) \ 245 V(CALL_NON_FUNCTION, 0) \ 246 V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \ 247 V(CALL_FUNCTION_PROXY, 1) \ 248 V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \ 249 V(TO_OBJECT, 0) \ 250 V(TO_NUMBER, 0) \ 251 V(TO_STRING, 0) \ 252 V(STRING_ADD_LEFT, 1) \ 253 V(STRING_ADD_RIGHT, 1) \ 254 V(APPLY_PREPARE, 1) \ 255 V(APPLY_OVERFLOW, 1) 256 257 258class BuiltinFunctionTable; 259class ObjectVisitor; 260 261 262class Builtins { 263 public: 264 ~Builtins(); 265 266 // Generate all builtin code objects. Should be called once during 267 // isolate initialization. 268 void SetUp(bool create_heap_objects); 269 void TearDown(); 270 271 // Garbage collection support. 272 void IterateBuiltins(ObjectVisitor* v); 273 274 // Disassembler support. 275 const char* Lookup(byte* pc); 276 277 enum Name { 278#define DEF_ENUM_C(name, ignore) k##name, 279#define DEF_ENUM_A(name, kind, state, extra) k##name, 280 BUILTIN_LIST_C(DEF_ENUM_C) 281 BUILTIN_LIST_A(DEF_ENUM_A) 282 BUILTIN_LIST_DEBUG_A(DEF_ENUM_A) 283#undef DEF_ENUM_C 284#undef DEF_ENUM_A 285 builtin_count 286 }; 287 288 enum CFunctionId { 289#define DEF_ENUM_C(name, ignore) c_##name, 290 BUILTIN_LIST_C(DEF_ENUM_C) 291#undef DEF_ENUM_C 292 cfunction_count 293 }; 294 295 enum JavaScript { 296#define DEF_ENUM(name, ignore) name, 297 BUILTINS_LIST_JS(DEF_ENUM) 298#undef DEF_ENUM 299 id_count 300 }; 301 302#define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name(); 303#define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ 304 Handle<Code> name(); 305 BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C) 306 BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A) 307 BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A) 308#undef DECLARE_BUILTIN_ACCESSOR_C 309#undef DECLARE_BUILTIN_ACCESSOR_A 310 311 Code* builtin(Name name) { 312 // Code::cast cannot be used here since we access builtins 313 // during the marking phase of mark sweep. See IC::Clear. 314 return reinterpret_cast<Code*>(builtins_[name]); 315 } 316 317 Address builtin_address(Name name) { 318 return reinterpret_cast<Address>(&builtins_[name]); 319 } 320 321 static Address c_function_address(CFunctionId id) { 322 return c_functions_[id]; 323 } 324 325 static const char* GetName(JavaScript id) { return javascript_names_[id]; } 326 static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; } 327 Handle<Code> GetCode(JavaScript id, bool* resolved); 328 static int NumberOfJavaScriptBuiltins() { return id_count; } 329 330 bool is_initialized() const { return initialized_; } 331 332 private: 333 Builtins(); 334 335 // The external C++ functions called from the code. 336 static Address const c_functions_[cfunction_count]; 337 338 // Note: These are always Code objects, but to conform with 339 // IterateBuiltins() above which assumes Object**'s for the callback 340 // function f, we use an Object* array here. 341 Object* builtins_[builtin_count]; 342 const char* names_[builtin_count]; 343 static const char* const javascript_names_[id_count]; 344 static int const javascript_argc_[id_count]; 345 346 static void Generate_Adaptor(MacroAssembler* masm, 347 CFunctionId id, 348 BuiltinExtraArguments extra_args); 349 static void Generate_JSConstructCall(MacroAssembler* masm); 350 static void Generate_JSConstructStubCountdown(MacroAssembler* masm); 351 static void Generate_JSConstructStubGeneric(MacroAssembler* masm); 352 static void Generate_JSConstructStubApi(MacroAssembler* masm); 353 static void Generate_JSEntryTrampoline(MacroAssembler* masm); 354 static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm); 355 static void Generate_LazyCompile(MacroAssembler* masm); 356 static void Generate_LazyRecompile(MacroAssembler* masm); 357 static void Generate_NotifyDeoptimized(MacroAssembler* masm); 358 static void Generate_NotifyLazyDeoptimized(MacroAssembler* masm); 359 static void Generate_NotifyOSR(MacroAssembler* masm); 360 static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm); 361 362 static void Generate_FunctionCall(MacroAssembler* masm); 363 static void Generate_FunctionApply(MacroAssembler* masm); 364 365 static void Generate_InternalArrayCode(MacroAssembler* masm); 366 static void Generate_ArrayCode(MacroAssembler* masm); 367 static void Generate_ArrayConstructCode(MacroAssembler* masm); 368 369 static void Generate_StringConstructCode(MacroAssembler* masm); 370 static void Generate_OnStackReplacement(MacroAssembler* masm); 371 372 static void InitBuiltinFunctionTable(); 373 374 bool initialized_; 375 376 friend class BuiltinFunctionTable; 377 friend class Isolate; 378 379 DISALLOW_COPY_AND_ASSIGN(Builtins); 380}; 381 382} } // namespace v8::internal 383 384#endif // V8_BUILTINS_H_ 385