code-stubs.h revision 6ded16be15dd865a9b21ea304d5273c8be299c87
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_CODE_STUBS_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_CODE_STUBS_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "globals.h" 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// List of code stubs used on all platforms. The order in this list is important 37d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// as only the stubs up to and including RecordWrite allows nested stub calls. 38d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ALL_PLATFORMS(V) \ 39d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CallFunction) \ 40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(GenericBinaryOp) \ 41d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(StringAdd) \ 42e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(SubString) \ 43e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(StringCompare) \ 44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(SmiOp) \ 45d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(Compare) \ 46d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(RecordWrite) \ 47d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ConvertToDouble) \ 48d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(WriteInt32ToHeapNumber) \ 49d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(StackCheck) \ 50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastNewClosure) \ 51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastNewContext) \ 52e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastCloneShallowArray) \ 53402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu V(TranscendentalCache) \ 54e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(GenericUnaryOp) \ 55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(RevertToNumber) \ 56d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ToBoolean) \ 57d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(Instanceof) \ 58d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CounterOp) \ 59d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ArgumentsAccess) \ 60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(RegExpExec) \ 61402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu V(NumberToString) \ 62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CEntry) \ 634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke V(JSEntry) \ 644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke V(DebuggerStatement) 65d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 66d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// List of code stubs only used on ARM platforms. 67d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef V8_TARGET_ARCH_ARM 68d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ARM(V) \ 69d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(GetProperty) \ 70d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(SetProperty) \ 71d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(InvokeBuiltin) \ 72d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(RegExpCEntry) 73d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#else 74d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ARM(V) 75d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 76d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Combined list of code stubs. 78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST(V) \ 79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST_ALL_PLATFORMS(V) \ 80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST_ARM(V) 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Stub is base classes of all stubs. 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodeStub BASE_EMBEDDED { 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Major { 86d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define DEF_ENUM(name) name, 87d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST(DEF_ENUM) 88d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#undef DEF_ENUM 89d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block NoCache, // marker for stubs that do custom caching 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_IDS 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Retrieve the code for the stub. Generate the code if needed. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> GetCode(); 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Retrieve the code for the stub if already generated. Do not 97e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // generate the code if not already generated and instead return a 98e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // retry after GC Failure object. 99e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Object* TryGetCode(); 100e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Major MajorKeyFromKey(uint32_t key) { 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<Major>(MajorKeyBits::decode(key)); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int MinorKeyFromKey(uint32_t key) { 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MinorKeyBits::decode(key); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 1073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const char* MajorName(Major major_key, bool allow_unknown_keys); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~CodeStub() {} 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Override these methods to provide a custom caching mechanism for 112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // an individual type of code stub. 113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual bool GetCustomCache(Code** code_out) { return false; } 114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual void SetCustomCache(Code* value) { } 115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block virtual bool has_custom_cache() { return false; } 116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMajorBits = 5; 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMinorBits = kBitsPerInt - kSmiTagSize - kMajorBits; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Lookup the code in the (possibly custom) cache. 123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool FindCodeInCache(Code** code_out); 124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Nonvirtual wrapper around the stub-specific Generate function. Call 126e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // this function to set up the macro assembler and generate the code. 127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void GenerateCode(MacroAssembler* masm); 128e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generates the assembler code for the stub. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Generate(MacroAssembler* masm) = 0; 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Perform bookkeeping required after code generation when stub code is 133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // initially generated. 134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void RecordCodeGeneration(Code* code, MacroAssembler* masm); 135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns information for computing the number key. 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Major MajorKey() = 0; 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual int MinorKey() = 0; 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The CallFunctionStub needs to override this so it can encode whether a 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lazily generated function should be fully optimized or not. 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual InLoopFlag InLoop() { return NOT_IN_LOOP; } 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // GenericBinaryOpStub needs to override this. 1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual int GetCodeKind(); 1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // GenericBinaryOpStub needs to override this. 1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual InlineCacheState GetICState() { 1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return UNINITIALIZED; 1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns a name for logging/debugging purposes. 1533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu virtual const char* GetName() { return MajorName(MajorKey(), false); } 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print() { PrintF("%s\n", GetName()); } 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the key based on major and minor. 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t GetKey() { 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MinorKeyBits::encode(MinorKey()) | 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MajorKeyBits::encode(MajorKey()); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool AllowsStubCalls() { return MajorKey() <= RecordWrite; } 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {}; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {}; 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class BreakPointIterator; 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_CODE_STUBS_H_ 177