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