13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "globals.h" 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "codegen.h" 346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// List of code stubs used on all platforms. 39d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ALL_PLATFORMS(V) \ 40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CallFunction) \ 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(CallConstruct) \ 42257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch V(UnaryOp) \ 43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch V(BinaryOp) \ 44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(StringAdd) \ 45e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(SubString) \ 46e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(StringCompare) \ 47d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(Compare) \ 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(CompareIC) \ 49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(MathPow) \ 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(RecordWrite) \ 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(StoreBufferOverflow) \ 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(RegExpExec) \ 53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(TranscendentalCache) \ 54086aeeaae12517475c22695a200be45495516549Ben Murdoch V(Instanceof) \ 55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ConvertToDouble) \ 56d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(WriteInt32ToHeapNumber) \ 57d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(StackCheck) \ 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(Interrupt) \ 59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastNewClosure) \ 60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastNewContext) \ 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(FastNewBlockContext) \ 62e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastCloneShallowArray) \ 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(FastCloneShallowObject) \ 64d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ToBoolean) \ 651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block V(ToNumber) \ 66d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ArgumentsAccess) \ 67b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(RegExpConstructResult) \ 68402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu V(NumberToString) \ 69d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CEntry) \ 704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke V(JSEntry) \ 713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V(KeyedLoadElement) \ 723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V(KeyedStoreElement) \ 73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch V(DebuggerStatement) \ 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(StringDictionaryLookup) \ 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ElementsTransitionAndStore) \ 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(StoreArrayLiteralElement) 77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// List of code stubs only used on ARM platforms. 79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef V8_TARGET_ARCH_ARM 80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ARM(V) \ 81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(GetProperty) \ 82d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(SetProperty) \ 83d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(InvokeBuiltin) \ 841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block V(RegExpCEntry) \ 851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block V(DirectCEntry) 86d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#else 87d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ARM(V) 88d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 89d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// List of code stubs only used on MIPS platforms. 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef V8_TARGET_ARCH_MIPS 9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CODE_STUB_LIST_MIPS(V) \ 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch V(RegExpCEntry) \ 94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch V(DirectCEntry) 9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define CODE_STUB_LIST_MIPS(V) 9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 99d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Combined list of code stubs. 100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST(V) \ 101d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST_ALL_PLATFORMS(V) \ 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CODE_STUB_LIST_ARM(V) \ 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CODE_STUB_LIST_MIPS(V) 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Mode to overwrite BinaryExpression values. 10680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; 10780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum UnaryOverwriteMode { UNARY_OVERWRITE, UNARY_NO_OVERWRITE }; 10880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 10980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Stub is base classes of all stubs. 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodeStub BASE_EMBEDDED { 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Major { 114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define DEF_ENUM(name) name, 115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST(DEF_ENUM) 116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#undef DEF_ENUM 117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block NoCache, // marker for stubs that do custom caching 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_IDS 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Retrieve the code for the stub. Generate the code if needed. 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> GetCode(); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Major MajorKeyFromKey(uint32_t key) { 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<Major>(MajorKeyBits::decode(key)); 1269ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int MinorKeyFromKey(uint32_t key) { 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MinorKeyBits::decode(key); 1299ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 13080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 13180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Gets the major key from a code object that is a code stub or binary op IC. 13280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static Major GetMajorKey(Code* code_stub) { 13380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return static_cast<Major>(code_stub->major_key()); 13480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 13580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const char* MajorName(Major major_key, bool allow_unknown_keys); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~CodeStub() {} 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool CompilingCallsToThisStubIsGCSafe() { 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_pregenerated = IsPregenerated(); 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* code = NULL; 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(!is_pregenerated || FindCodeInCache(&code)); 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return is_pregenerated; 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // See comment above, where Instanceof is defined. 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsPregenerated() { return false; } 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateStubsAheadOfTime(); 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateFPStubs(); 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Some stubs put untagged junk on the stack that cannot be scanned by the 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // GC. This means that we must be statically sure that no GC can occur while 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // they are running. If that is the case they should override this to return 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // true, which will cause an assertion if we try to call something that can 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // GC or if we try to put a stack frame on top of the junk, which would not 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result in a traversable stack. 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return true; } 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Lookup the code in the (possibly custom) cache. 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool FindCodeInCache(Code** code_out); 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kMajorBits = 6; 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMinorBits = kBitsPerInt - kSmiTagSize - kMajorBits; 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 169e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Nonvirtual wrapper around the stub-specific Generate function. Call 170e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // this function to set up the macro assembler and generate the code. 171e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void GenerateCode(MacroAssembler* masm); 172e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generates the assembler code for the stub. 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Generate(MacroAssembler* masm) = 0; 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Perform bookkeeping required after code generation when stub code is 177e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // initially generated. 178e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void RecordCodeGeneration(Code* code, MacroAssembler* masm); 179e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Finish the code object after it has been generated. 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { } 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Activate newly generated stub. Is called after 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // registering stub in the stub cache. 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Activate(Code* code) { } 186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns information for computing the number key. 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Major MajorKey() = 0; 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual int MinorKey() = 0; 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // BinaryOpStub needs to override this. 1926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual int GetCodeKind(); 1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 194257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // BinaryOpStub needs to override this. 1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual InlineCacheState GetICState() { 1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return UNINITIALIZED; 1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Add the code to a specialized cache, specific to an individual 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // stub type. Please note, this method must add the code object to a 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // roots object, otherwise we will remove the code during GC. 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void AddToSpecialCache(Handle<Code> new_object) { } 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Find code in a specialized cache, work is delegated to the specific stub. 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool FindCodeInSpecialCache(Code** code_out) { return false; } 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If a stub uses a special cache override this. 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool UseSpecialCache() { return false; } 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns a name for logging/debugging purposes. 211589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<const char> GetName(); 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void PrintName(StringStream* stream); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Returns whether the code generated for this stub needs to be allocated as 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // a fixed (non-moveable) code object. 21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block virtual bool NeedsImmovableCode() { return false; } 21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the key based on major and minor. 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t GetKey() { 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MinorKeyBits::encode(MinorKey()) | 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MajorKeyBits::encode(MajorKey()); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {}; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {}; 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class BreakPointIterator; 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Helper interface to prepare to/restore after making runtime calls. 23380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass RuntimeCallHelper { 23480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 23580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual ~RuntimeCallHelper() {} 23680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void BeforeCall(MacroAssembler* masm) const = 0; 23880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void AfterCall(MacroAssembler* masm) const = 0; 24080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen protected: 24280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RuntimeCallHelper() {} 24380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 24580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper); 24680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 24780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} } // namespace v8::internal 24980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 25080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#if V8_TARGET_ARCH_IA32 25180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "ia32/code-stubs-ia32.h" 25280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#elif V8_TARGET_ARCH_X64 25380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "x64/code-stubs-x64.h" 25480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#elif V8_TARGET_ARCH_ARM 25580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "arm/code-stubs-arm.h" 25680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#elif V8_TARGET_ARCH_MIPS 25780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "mips/code-stubs-mips.h" 25880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#else 25980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#error Unsupported target architecture. 26080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 26180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsennamespace v8 { 26380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsennamespace internal { 26480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// RuntimeCallHelper implementation used in stubs: enters/leaves a 26780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// newly created internal frame before/after the runtime call. 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass StubRuntimeCallHelper : public RuntimeCallHelper { 26980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StubRuntimeCallHelper() {} 27180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void BeforeCall(MacroAssembler* masm) const; 27380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void AfterCall(MacroAssembler* masm) const; 27580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 27680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Trivial RuntimeCallHelper implementation. 27980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass NopRuntimeCallHelper : public RuntimeCallHelper { 28080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 28180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NopRuntimeCallHelper() {} 28280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void BeforeCall(MacroAssembler* masm) const {} 28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void AfterCall(MacroAssembler* masm) const {} 28680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 28780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StackCheckStub : public CodeStub { 29080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 29180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StackCheckStub() { } 29280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 29380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 29480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 29580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 29680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return StackCheck; } 29780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 29880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 29980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 30080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass InterruptStub : public CodeStub { 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InterruptStub() { } 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return Interrupt; } 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return 0; } 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockclass ToNumberStub: public CodeStub { 3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 3151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ToNumberStub() { } 3161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void Generate(MacroAssembler* masm); 3181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 3201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Major MajorKey() { return ToNumber; } 3211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int MinorKey() { return 0; } 3221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 3231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 32580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass FastNewClosureStub : public CodeStub { 32680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastNewClosureStub(LanguageMode language_mode) 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : language_mode_(language_mode) { } 32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 33080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 33180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 33380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return FastNewClosure; } 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return language_mode_ == CLASSIC_MODE 3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? kNonStrictMode : kStrictMode; } 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode language_mode_; 33880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 33980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass FastNewContextStub : public CodeStub { 34280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 34380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaximumSlots = 64; 34480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen explicit FastNewContextStub(int slots) : slots_(slots) { 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); 34780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 34880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 35080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 35280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int slots_; 35380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return FastNewContext; } 35580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return slots_; } 35680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 35780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 35880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass FastNewBlockContextStub : public CodeStub { 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kMaximumSlots = 64; 3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastNewBlockContextStub(int slots) : slots_(slots) { 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int slots_; 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return FastNewBlockContext; } 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return slots_; } 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass FastCloneShallowArrayStub : public CodeStub { 37880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 37980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Maximum length of copied elements array. 38080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaximumClonedLength = 8; 38180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 38280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen enum Mode { 38380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CLONE_ELEMENTS, 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CLONE_DOUBLE_ELEMENTS, 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch COPY_ON_WRITE_ELEMENTS, 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CLONE_ANY_ELEMENTS 38780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 38880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 38980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen FastCloneShallowArrayStub(Mode mode, int length) 39080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : mode_(mode), 39180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) { 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_GE(length_, 0); 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_LE(length_, kMaximumClonedLength); 39480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 39580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 39680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 39780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 39880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 39980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Mode mode_; 40080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int length_; 40180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 40280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return FastCloneShallowArray; } 40380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(mode_ == 0 || mode_ == 1 || mode_ == 2 || mode_ == 3); 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return length_ * 4 + mode_; 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass FastCloneShallowObjectStub : public CodeStub { 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Maximum number of properties in copied object. 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kMaximumClonedProperties = 6; 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastCloneShallowObjectStub(int length) : length_(length) { 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_GE(length_, 0); 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_LE(length_, kMaximumClonedProperties); 418592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length_; 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return FastCloneShallowObject; } 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return length_; } 427592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}; 428592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 429592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 43080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass InstanceofStub: public CodeStub { 43180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum Flags { 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kNoFlags = 0, 434086aeeaae12517475c22695a200be45495516549Ben Murdoch kArgsInRegisters = 1 << 0, 435086aeeaae12517475c22695a200be45495516549Ben Murdoch kCallSiteInlineCheck = 1 << 1, 436086aeeaae12517475c22695a200be45495516549Ben Murdoch kReturnTrueFalseObject = 1 << 2 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit InstanceofStub(Flags flags) : flags_(flags) { } 440086aeeaae12517475c22695a200be45495516549Ben Murdoch 441086aeeaae12517475c22695a200be45495516549Ben Murdoch static Register left(); 442086aeeaae12517475c22695a200be45495516549Ben Murdoch static Register right(); 44380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 44480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 44580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 44680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 44780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return Instanceof; } 448086aeeaae12517475c22695a200be45495516549Ben Murdoch int MinorKey() { return static_cast<int>(flags_); } 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 450086aeeaae12517475c22695a200be45495516549Ben Murdoch bool HasArgsInRegisters() const { 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (flags_ & kArgsInRegisters) != 0; 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 454086aeeaae12517475c22695a200be45495516549Ben Murdoch bool HasCallSiteInlineCheck() const { 455086aeeaae12517475c22695a200be45495516549Ben Murdoch return (flags_ & kCallSiteInlineCheck) != 0; 456086aeeaae12517475c22695a200be45495516549Ben Murdoch } 457086aeeaae12517475c22695a200be45495516549Ben Murdoch 458086aeeaae12517475c22695a200be45495516549Ben Murdoch bool ReturnTrueFalseObject() const { 459086aeeaae12517475c22695a200be45495516549Ben Murdoch return (flags_ & kReturnTrueFalseObject) != 0; 460086aeeaae12517475c22695a200be45495516549Ben Murdoch } 461086aeeaae12517475c22695a200be45495516549Ben Murdoch 4623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 463086aeeaae12517475c22695a200be45495516549Ben Murdoch 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Flags flags_; 46580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 46680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 46780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass MathPowStub: public CodeStub { 469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK}; 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit MathPowStub(ExponentType exponent_type) 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : exponent_type_(exponent_type) { } 474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate(MacroAssembler* masm); 475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual CodeStub::Major MajorKey() { return MathPow; } 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual int MinorKey() { return exponent_type_; } 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExponentType exponent_type_; 481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass ICCompareStub: public CodeStub { 485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ICCompareStub(Token::Value op, CompareIC::State state) 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : op_(op), state_(state) { 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(Token::IsCompareOp(op)); 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate(MacroAssembler* masm); 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void set_known_map(Handle<Map> map) { known_map_ = map; } 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 496b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class OpField: public BitField<int, 0, 3> { }; 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class StateField: public BitField<int, 3, 5> { }; 498b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_compare_state(state_); 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual CodeStub::Major MajorKey() { return CompareIC; } 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int MinorKey(); 505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int GetCodeKind() { return Code::COMPARE_IC; } 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateSmis(MacroAssembler* masm); 509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateHeapNumbers(MacroAssembler* masm); 510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateSymbols(MacroAssembler* masm); 511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateStrings(MacroAssembler* masm); 512b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateObjects(MacroAssembler* masm); 513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateMiss(MacroAssembler* masm); 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void GenerateKnownObjects(MacroAssembler* masm); 515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool strict() const { return op_ == Token::EQ_STRICT; } 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition GetCondition() const { return CompareIC::ComputeCondition(op_); } 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void AddToSpecialCache(Handle<Code> new_object); 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool FindCodeInSpecialCache(Code** code_out); 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; } 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::Value op_; 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompareIC::State state_; 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> known_map_; 52680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 52780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 52880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// Flags that control the compare stub code generation. 5300d5e116f6aee03185f237311a943491bb079a768Kristian Monsenenum CompareFlags { 5310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_COMPARE_FLAGS = 0, 5320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_SMI_COMPARE_IN_STUB = 1 << 0, 5330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_NUMBER_COMPARE_IN_STUB = 1 << 1, 5340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CANT_BOTH_BE_NAN = 1 << 2 5350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 5360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochenum NaNInformation { 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kBothCouldBeNaN, 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kCantBothBeNaN 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 54480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass CompareStub: public CodeStub { 54580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 54680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CompareStub(Condition cc, 54780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool strict, 5480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompareFlags flags, 5490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register lhs, 5500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register rhs) : 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cc_(cc), 55280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen strict_(strict), 5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), 5540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), 5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), 55680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen lhs_(lhs), 5573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch rhs_(rhs) { } 55880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompareStub(Condition cc, 5600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool strict, 5610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompareFlags flags) : 5620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen cc_(cc), 5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen strict_(strict), 5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), 5650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), 5660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), 5670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen lhs_(no_reg), 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch rhs_(no_reg) { } 5690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 57080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 57180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 57280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 57380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Condition cc_; 57480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool strict_; 57580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Only used for 'equal' comparisons. Tells the stub that we already know 57680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // that at least one side of the comparison is not NaN. This allows the 57780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // stub to use object identity in the positive case. We ignore it when 57880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // generating the minor key for other comparisons to avoid creating more 57980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // stubs. 58080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool never_nan_nan_; 58180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Do generate the number comparison code in the stub. Stubs without number 58280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // comparison code is used when the number comparison has been inlined, and 58380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the stub will be called if one of the operands is not a number. 58480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool include_number_compare_; 5850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Generate the comparison code for two smi operands in the stub. 5870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool include_smi_compare_; 5880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 58980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Register holding the left hand side of the comparison if the stub gives 59080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // a choice, no_reg otherwise. 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 59280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register lhs_; 59380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Register holding the right hand side of the comparison if the stub gives 59480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // a choice, no_reg otherwise. 59580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register rhs_; 59680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Encoding of the minor key in 16 bits. 59880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class StrictField: public BitField<bool, 0, 1> {}; 59980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class NeverNanNanField: public BitField<bool, 1, 1> {}; 60080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class IncludeNumberCompareField: public BitField<bool, 2, 1> {}; 6010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class IncludeSmiCompareField: public BitField<bool, 3, 1> {}; 6020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class RegisterField: public BitField<bool, 4, 1> {}; 6030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class ConditionField: public BitField<int, 5, 11> {}; 60480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 60580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return Compare; } 60680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 60780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey(); 60880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int GetCodeKind() { return Code::COMPARE_IC; } 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_compare_state(CompareIC::GENERIC); 612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 61480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Branch to the label if the given object isn't a symbol. 61580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void BranchIfNonSymbol(MacroAssembler* masm, 61680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* label, 61780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register object, 61880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch); 61980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 62080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Unfortunately you have to run without snapshots to see most of these 62180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // names in the profile since most compare stubs end up in the snapshot. 6223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 62380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 62480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 62580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 62680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass CEntryStub : public CodeStub { 62780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit CEntryStub(int result_size, 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_doubles = kDontSaveFPRegs) 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : result_size_(result_size), save_doubles_(save_doubles) { } 63180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 63280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The version of this stub that doesn't save doubles is generated ahead of 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // time, so it's OK to call it from other stubs that can't cope with GC during 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // their code generation. On machines that always have gp registers (x64) we 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // can generate both variants ahead of time. 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsPregenerated(); 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateAheadOfTime(); 64080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 64280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateCore(MacroAssembler* masm, 64380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* throw_normal_exception, 64480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* throw_termination_exception, 64580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* throw_out_of_memory_exception, 64680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool do_gc, 6471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool always_allocate_scope); 64880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Number of pointers/values returned. 65080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const int result_size_; 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_doubles_; 65280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 65380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return CEntry; } 65480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey(); 65580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 65644f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool NeedsImmovableCode(); 65780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 65880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 65980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass JSEntryStub : public CodeStub { 66180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 66280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSEntryStub() { } 66380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm) { GenerateBody(masm, false); } 66580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen protected: 66780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateBody(MacroAssembler* masm, bool is_construct); 66880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 67080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return JSEntry; } 67180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code); 6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int handler_offset_; 67680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 67780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 67880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 67980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass JSConstructEntryStub : public JSEntryStub { 68080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 68180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSConstructEntryStub() { } 68280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm) { GenerateBody(masm, true); } 68480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 68680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 1; } 68780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 6883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream) { 6893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch stream->Add("JSConstructEntryStub"); 6903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 69180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 69280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 69380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 69480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass ArgumentsAccessStub: public CodeStub { 69580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 69680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen enum Type { 69780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen READ_ELEMENT, 6983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NEW_NON_STRICT_FAST, 6993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NEW_NON_STRICT_SLOW, 70044f0eee88ff00398ff7f715fab053374d808c90dSteve Block NEW_STRICT 70180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 70280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 70380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen explicit ArgumentsAccessStub(Type type) : type_(type) { } 70480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 70580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 70680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Type type_; 70780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 70880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return ArgumentsAccess; } 70980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return type_; } 71080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 71180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 71280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateReadElement(MacroAssembler* masm); 7133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void GenerateNewStrict(MacroAssembler* masm); 7143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void GenerateNewNonStrictFast(MacroAssembler* masm); 7153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void GenerateNewNonStrictSlow(MacroAssembler* masm); 71680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 71880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 71980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass RegExpExecStub: public CodeStub { 72280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 72380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RegExpExecStub() { } 72480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 72680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return RegExpExec; } 72780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 72880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 73080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 73180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 73280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass RegExpConstructResultStub: public CodeStub { 734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch RegExpConstructResultStub() { } 736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Major MajorKey() { return RegExpConstructResult; } 739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int MinorKey() { return 0; } 740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Generate(MacroAssembler* masm); 742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 74580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass CallFunctionStub: public CodeStub { 74680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 747589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch CallFunctionStub(int argc, CallFunctionFlags flags) 748589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch : argc_(argc), flags_(flags) { } 74980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 75080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 75180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_has_function_cache(RecordCallTarget()); 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 756086aeeaae12517475c22695a200be45495516549Ben Murdoch static int ExtractArgcFromMinorKey(int minor_key) { 757086aeeaae12517475c22695a200be45495516549Ben Murdoch return ArgcBits::decode(minor_key); 758086aeeaae12517475c22695a200be45495516549Ben Murdoch } 759086aeeaae12517475c22695a200be45495516549Ben Murdoch 76080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 76180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int argc_; 76280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CallFunctionFlags flags_; 76380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PrintName(StringStream* stream); 76580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 76680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class FlagBits: public BitField<CallFunctionFlags, 0, 2> {}; 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ArgcBits: public BitField<unsigned, 2, 32 - 2> {}; 76980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 77080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return CallFunction; } 77180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { 77280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Encode the parameters in a unique 32 bit value. 773589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return FlagBits::encode(flags_) | ArgcBits::encode(argc_); 77480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 77580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool ReceiverMightBeImplicit() { 777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0; 77880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool RecordCallTarget() { 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (flags_ & RECORD_CALL_TARGET) != 0; 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass CallConstructStub: public CodeStub { 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {} 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_has_function_cache(RecordCallTarget()); 7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallFunctionFlags flags_; 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void PrintName(StringStream* stream); 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return CallConstruct; } 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return flags_; } 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool RecordCallTarget() { 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (flags_ & RECORD_CALL_TARGET) != 0; 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}; 8085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 8095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 81080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum StringIndexFlags { 81180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Accepts smis or heap numbers. 81280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen STRING_INDEX_IS_NUMBER, 81380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 81480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Accepts smis or heap numbers that are valid array indices 81580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // (ECMA-262 15.4). Invalid indices are reported as being out of 81680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // range. 81780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen STRING_INDEX_IS_ARRAY_INDEX 81880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 81980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 82080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 82180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Generates code implementing String.prototype.charCodeAt. 82280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 82380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Only supports the case when the receiver is a string and the index 82480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// is a number (smi or heap number) that is a valid index into the 82580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// string. Additional index constraints are specified by the 82680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// flags. Otherwise, bails out to the provided labels. 82780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 82880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Register usage: |object| may be changed to another string in a way 82980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// that doesn't affect charCodeAt/charAt semantics, |index| is 83080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// preserved, |scratch| and |result| are clobbered. 83180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCharCodeAtGenerator { 83280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 83380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharCodeAtGenerator(Register object, 83480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register index, 83580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result, 83680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* receiver_not_string, 83780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_not_number, 83880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_out_of_range, 83980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringIndexFlags index_flags) 84080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : object_(object), 84180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_(index), 84280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen result_(result), 84380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen receiver_not_string_(receiver_not_string), 84480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_not_number_(index_not_number), 84580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_out_of_range_(index_out_of_range), 84680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_flags_(index_flags) { 84780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!result_.is(object_)); 84880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!result_.is(index_)); 84980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 85080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the fast case code. On the fallthrough path |result| 85280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // register contains the result. 85380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateFast(MacroAssembler* masm); 85480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the slow case code. Must not be naturally 85680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reachable. Expected to be put after a ret instruction (e.g., in 85780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // deferred code). Always jumps back to the fast case. 85880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateSlow(MacroAssembler* masm, 85980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const RuntimeCallHelper& call_helper); 86080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 86180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 86280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register object_; 86380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register index_; 86480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result_; 86580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 86680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* receiver_not_string_; 86780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_not_number_; 86880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_out_of_range_; 86980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 87080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringIndexFlags index_flags_; 87180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 87280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label call_runtime_; 87380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label index_not_smi_; 87480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label got_smi_index_; 87580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label exit_; 87680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 87780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator); 87880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 87980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 88080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 88180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Generates code for creating a one-char string from a char code. 88280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCharFromCodeGenerator { 88380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 88480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharFromCodeGenerator(Register code, 88580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result) 88680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : code_(code), 88780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen result_(result) { 88880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!code_.is(result_)); 88980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 89080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 89180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the fast case code. On the fallthrough path |result| 89280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // register contains the result. 89380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateFast(MacroAssembler* masm); 89480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 89580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the slow case code. Must not be naturally 89680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reachable. Expected to be put after a ret instruction (e.g., in 89780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // deferred code). Always jumps back to the fast case. 89880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateSlow(MacroAssembler* masm, 89980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const RuntimeCallHelper& call_helper); 90080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 90280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register code_; 90380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result_; 90480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label slow_case_; 90680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label exit_; 90780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator); 90980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 91080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 91180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 91280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Generates code implementing String.prototype.charAt. 91380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 91480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Only supports the case when the receiver is a string and the index 91580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// is a number (smi or heap number) that is a valid index into the 91680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// string. Additional index constraints are specified by the 91780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// flags. Otherwise, bails out to the provided labels. 91880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 91980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Register usage: |object| may be changed to another string in a way 92080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// that doesn't affect charCodeAt/charAt semantics, |index| is 92180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// preserved, |scratch1|, |scratch2|, and |result| are clobbered. 92280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCharAtGenerator { 92380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 92480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharAtGenerator(Register object, 92580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register index, 9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 92780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result, 92880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* receiver_not_string, 92980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_not_number, 93080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_out_of_range, 93180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringIndexFlags index_flags) 93280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : char_code_at_generator_(object, 93380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index, 9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, 93580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen receiver_not_string, 93680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_not_number, 93780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_out_of_range, 93880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_flags), 9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char_from_code_generator_(scratch, result) {} 94080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 94180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the fast case code. On the fallthrough path |result| 94280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // register contains the result. 94380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateFast(MacroAssembler* masm); 94480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 94580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the slow case code. Must not be naturally 94680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reachable. Expected to be put after a ret instruction (e.g., in 94780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // deferred code). Always jumps back to the fast case. 94880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateSlow(MacroAssembler* masm, 94980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const RuntimeCallHelper& call_helper); 95080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 95180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 95280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharCodeAtGenerator char_code_at_generator_; 95380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharFromCodeGenerator char_from_code_generator_; 95480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 95580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator); 95680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 95780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 958086aeeaae12517475c22695a200be45495516549Ben Murdoch 959086aeeaae12517475c22695a200be45495516549Ben Murdochclass AllowStubCallsScope { 960086aeeaae12517475c22695a200be45495516549Ben Murdoch public: 961086aeeaae12517475c22695a200be45495516549Ben Murdoch AllowStubCallsScope(MacroAssembler* masm, bool allow) 962086aeeaae12517475c22695a200be45495516549Ben Murdoch : masm_(masm), previous_allow_(masm->allow_stub_calls()) { 963086aeeaae12517475c22695a200be45495516549Ben Murdoch masm_->set_allow_stub_calls(allow); 964086aeeaae12517475c22695a200be45495516549Ben Murdoch } 965086aeeaae12517475c22695a200be45495516549Ben Murdoch ~AllowStubCallsScope() { 966086aeeaae12517475c22695a200be45495516549Ben Murdoch masm_->set_allow_stub_calls(previous_allow_); 967086aeeaae12517475c22695a200be45495516549Ben Murdoch } 968086aeeaae12517475c22695a200be45495516549Ben Murdoch 969086aeeaae12517475c22695a200be45495516549Ben Murdoch private: 970086aeeaae12517475c22695a200be45495516549Ben Murdoch MacroAssembler* masm_; 971086aeeaae12517475c22695a200be45495516549Ben Murdoch bool previous_allow_; 972086aeeaae12517475c22695a200be45495516549Ben Murdoch 973086aeeaae12517475c22695a200be45495516549Ben Murdoch DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope); 974086aeeaae12517475c22695a200be45495516549Ben Murdoch}; 975086aeeaae12517475c22695a200be45495516549Ben Murdoch 976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass KeyedLoadElementStub : public CodeStub { 978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 979589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch explicit KeyedLoadElementStub(ElementsKind elements_kind) 9803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : elements_kind_(elements_kind) 9813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { } 982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Major MajorKey() { return KeyedLoadElement; } 9843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int MinorKey() { return elements_kind_; } 985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 989589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ElementsKind elements_kind_; 990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub); 992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 9953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass KeyedStoreElementStub : public CodeStub { 996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 9973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch KeyedStoreElementStub(bool is_js_array, 9983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind, 9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode) 10003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : is_js_array_(is_js_array), 10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind_(elements_kind), 10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch grow_mode_(grow_mode) { } 1003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Major MajorKey() { return KeyedStoreElement; } 10053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int MinorKey() { 10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsKindBits::encode(elements_kind_) | 10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsJSArrayBits::encode(is_js_array_) | 10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GrowModeBits::encode(grow_mode_); 10093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 1012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1013257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; 10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class GrowModeBits: public BitField<KeyedAccessGrowMode, 8, 1> {}; 10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class IsJSArrayBits: public BitField<bool, 9, 1> {}; 10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1018257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool is_js_array_; 1019589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ElementsKind elements_kind_; 10203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode_; 1021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub); 1023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 1024257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass ToBooleanStub: public CodeStub { 1027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 102869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch enum Type { 102969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch UNDEFINED, 103069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch BOOLEAN, 103169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch NULL_TYPE, 103269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SMI, 103369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SPEC_OBJECT, 103469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STRING, 103569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HEAP_NUMBER, 103669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch NUMBER_OF_TYPES 103769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch }; 103869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 103969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // At most 8 different types can be distinguished, because the Code object 104069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // only has room for a single byte to hold a set of these types. :-P 104169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(NUMBER_OF_TYPES <= 8); 104269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 104369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch class Types { 104469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 104569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Types() {} 104669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch explicit Types(byte bits) : set_(bits) {} 104769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 104869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool IsEmpty() const { return set_.IsEmpty(); } 104969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool Contains(Type type) const { return set_.Contains(type); } 105069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void Add(Type type) { set_.Add(type); } 105169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch byte ToByte() const { return set_.ToIntegral(); } 105269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void Print(StringStream* stream) const; 105369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void TraceTransition(Types to) const; 105469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool Record(Handle<Object> object); 105569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool NeedsMap() const; 105669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool CanBeUndetectable() const; 105769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 105869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private: 105969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch EnumSet<Type, byte> set_; 106069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch }; 106169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 106269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static Types no_types() { return Types(); } 106369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static Types all_types() { return Types((1 << NUMBER_OF_TYPES) - 1); } 106469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 106569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch explicit ToBooleanStub(Register tos, Types types = Types()) 106669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : tos_(tos), types_(types) { } 1067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void Generate(MacroAssembler* masm); 106969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual int GetCodeKind() { return Code::TO_BOOLEAN_IC; } 107069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual void PrintName(StringStream* stream); 1071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool SometimesSetsUpAFrame() { return false; } 10733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 10753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Major MajorKey() { return ToBoolean; } 107669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToByte(); } 107769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void FinishCode(Handle<Code> code) { 107969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch code->set_to_boolean_state(types_.ToByte()); 108069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 108269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void CheckOddball(MacroAssembler* masm, 108369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Type type, 108469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap::RootListIndex value, 108569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool result); 108669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void GenerateTypeTransition(MacroAssembler* masm); 108769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 108869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Register tos_; 108969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Types types_; 1090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 1091257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass ElementsTransitionAndStoreStub : public CodeStub { 10943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsTransitionAndStoreStub(ElementsKind from, 10963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to, 10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_jsarray, 10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode, 10993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode) 11003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : from_(from), 11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_(to), 11023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch is_jsarray_(is_jsarray), 11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch strict_mode_(strict_mode), 11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch grow_mode_(grow_mode) {} 11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class FromBits: public BitField<ElementsKind, 0, 8> {}; 11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ToBits: public BitField<ElementsKind, 8, 8> {}; 11093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class IsJSArrayBits: public BitField<bool, 16, 1> {}; 11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class StrictModeBits: public BitField<StrictModeFlag, 17, 1> {}; 11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class GrowModeBits: public BitField<KeyedAccessGrowMode, 18, 1> {}; 11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return ElementsTransitionAndStore; } 11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { 11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return FromBits::encode(from_) | 11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToBits::encode(to_) | 11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsJSArrayBits::encode(is_jsarray_) | 11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeBits::encode(strict_mode_) | 11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GrowModeBits::encode(grow_mode_); 11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind from_; 11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_; 11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_jsarray_; 11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode_; 11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode_; 11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub); 11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass StoreArrayLiteralElementStub : public CodeStub { 11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 11363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit StoreArrayLiteralElementStub() {} 11373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Major MajorKey() { return StoreArrayLiteralElement; } 11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int MinorKey() { return 0; } 11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Generate(MacroAssembler* masm); 11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub); 11453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 11463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_CODE_STUBS_H_ 1150