code-stubs.h revision 086aeeaae12517475c22695a200be45495516549
1086aeeaae12517475c22695a200be45495516549Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_CODE_STUBS_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_CODE_STUBS_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "globals.h" 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// List of code stubs used on all platforms. The order in this list is important 37086aeeaae12517475c22695a200be45495516549Ben Murdoch// as only the stubs up to and including Instanceof allows nested stub calls. 38d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ALL_PLATFORMS(V) \ 39d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CallFunction) \ 40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(GenericBinaryOp) \ 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(TypeRecordingBinaryOp) \ 42d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(StringAdd) \ 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(StringCharAt) \ 44e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(SubString) \ 45e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(StringCompare) \ 46d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(SmiOp) \ 47d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(Compare) \ 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(CompareIC) \ 49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(MathPow) \ 50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(TranscendentalCache) \ 51086aeeaae12517475c22695a200be45495516549Ben Murdoch V(Instanceof) \ 52d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ConvertToDouble) \ 53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(WriteInt32ToHeapNumber) \ 548defd9ff6930b4e24729971a61cf7469daf119beSteve Block V(IntegerMod) \ 55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(StackCheck) \ 56e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastNewClosure) \ 57e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastNewContext) \ 58e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(FastCloneShallowArray) \ 59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(GenericUnaryOp) \ 60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(RevertToNumber) \ 61d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ToBoolean) \ 62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CounterOp) \ 63d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(ArgumentsAccess) \ 64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke V(RegExpExec) \ 65b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch V(RegExpConstructResult) \ 66402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu V(NumberToString) \ 67d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(CEntry) \ 684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke V(JSEntry) \ 694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke V(DebuggerStatement) 70d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 71d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// List of code stubs only used on ARM platforms. 72d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef V8_TARGET_ARCH_ARM 73d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ARM(V) \ 74d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(GetProperty) \ 75d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(SetProperty) \ 76d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(InvokeBuiltin) \ 77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block V(RegExpCEntry) 78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#else 79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST_ARM(V) 80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif 81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 82d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Combined list of code stubs. 83d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define CODE_STUB_LIST(V) \ 84d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST_ALL_PLATFORMS(V) \ 85d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST_ARM(V) 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Types of uncatchable exceptions. 8880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum UncatchableExceptionType { OUT_OF_MEMORY, TERMINATION }; 8980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 9080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Mode to overwrite BinaryExpression values. 9180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT }; 9280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum UnaryOverwriteMode { UNARY_OVERWRITE, UNARY_NO_OVERWRITE }; 9380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 9480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Stub is base classes of all stubs. 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodeStub BASE_EMBEDDED { 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum Major { 99d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#define DEF_ENUM(name) name, 100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CODE_STUB_LIST(DEF_ENUM) 101d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#undef DEF_ENUM 102d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block NoCache, // marker for stubs that do custom caching 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NUMBER_OF_IDS 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Retrieve the code for the stub. Generate the code if needed. 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> GetCode(); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Retrieve the code for the stub if already generated. Do not 110e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // generate the code if not already generated and instead return a 111e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // retry after GC Failure object. 1125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* TryGetCode(); 113e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Major MajorKeyFromKey(uint32_t key) { 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<Major>(MajorKeyBits::decode(key)); 1169ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int MinorKeyFromKey(uint32_t key) { 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MinorKeyBits::decode(key); 1199ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 12080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 12180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Gets the major key from a code object that is a code stub or binary op IC. 12280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static Major GetMajorKey(Code* code_stub) { 12380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return static_cast<Major>(code_stub->major_key()); 12480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 12580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu static const char* MajorName(Major major_key, bool allow_unknown_keys); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~CodeStub() {} 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const int kMajorBits = 6; 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kMinorBits = kBitsPerInt - kSmiTagSize - kMajorBits; 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Lookup the code in the (possibly custom) cache. 136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool FindCodeInCache(Code** code_out); 137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Nonvirtual wrapper around the stub-specific Generate function. Call 139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // this function to set up the macro assembler and generate the code. 140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void GenerateCode(MacroAssembler* masm); 141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Generates the assembler code for the stub. 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Generate(MacroAssembler* masm) = 0; 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Perform bookkeeping required after code generation when stub code is 146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // initially generated. 147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void RecordCodeGeneration(Code* code, MacroAssembler* masm); 148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Finish the code object after it has been generated. 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void FinishCode(Code* code) { } 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns information for computing the number key. 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual Major MajorKey() = 0; 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual int MinorKey() = 0; 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The CallFunctionStub needs to override this so it can encode whether a 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lazily generated function should be fully optimized or not. 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual InLoopFlag InLoop() { return NOT_IN_LOOP; } 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // GenericBinaryOpStub needs to override this. 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual int GetCodeKind(); 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // GenericBinaryOpStub needs to override this. 1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block virtual InlineCacheState GetICState() { 1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return UNINITIALIZED; 1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns a name for logging/debugging purposes. 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu virtual const char* GetName() { return MajorName(MajorKey(), false); } 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual void Print() { PrintF("%s\n", GetName()); } 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the key based on major and minor. 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t GetKey() { 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return MinorKeyBits::encode(MinorKey()) | 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MajorKeyBits::encode(MajorKey()); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 182086aeeaae12517475c22695a200be45495516549Ben Murdoch bool AllowsStubCalls() { return MajorKey() <= Instanceof; } 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {}; 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {}; 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class BreakPointIterator; 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 19180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Helper interface to prepare to/restore after making runtime calls. 19280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass RuntimeCallHelper { 19380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 19480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual ~RuntimeCallHelper() {} 19580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 19680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void BeforeCall(MacroAssembler* masm) const = 0; 19780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 19880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void AfterCall(MacroAssembler* masm) const = 0; 19980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 20080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen protected: 20180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RuntimeCallHelper() {} 20280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 20380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 20480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper); 20580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 20680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 20780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} } // namespace v8::internal 20880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 20980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#if V8_TARGET_ARCH_IA32 21080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "ia32/code-stubs-ia32.h" 21180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#elif V8_TARGET_ARCH_X64 21280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "x64/code-stubs-x64.h" 21380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#elif V8_TARGET_ARCH_ARM 21480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "arm/code-stubs-arm.h" 21580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#elif V8_TARGET_ARCH_MIPS 21680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "mips/code-stubs-mips.h" 21780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#else 21880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#error Unsupported target architecture. 21980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 22080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 22180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsennamespace v8 { 22280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsennamespace internal { 22380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 22480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// RuntimeCallHelper implementation used in stubs: enters/leaves a 22680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// newly created internal frame before/after the runtime call. 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass StubRuntimeCallHelper : public RuntimeCallHelper { 22880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StubRuntimeCallHelper() {} 23080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void BeforeCall(MacroAssembler* masm) const; 23280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void AfterCall(MacroAssembler* masm) const; 23480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 23580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 23780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Trivial RuntimeCallHelper implementation. 23880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass NopRuntimeCallHelper : public RuntimeCallHelper { 23980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 24080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NopRuntimeCallHelper() {} 24180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void BeforeCall(MacroAssembler* masm) const {} 24380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen virtual void AfterCall(MacroAssembler* masm) const {} 24580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 24680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 24880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StackCheckStub : public CodeStub { 24980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 25080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StackCheckStub() { } 25180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 25280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 25380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 25480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 25580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 25680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "StackCheckStub"; } 25780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 25880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return StackCheck; } 25980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 26080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 26180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass FastNewClosureStub : public CodeStub { 26480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 26580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 26680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 26880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "FastNewClosureStub"; } 26980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return FastNewClosure; } 27080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 27180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 27280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass FastNewContextStub : public CodeStub { 27580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 27680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaximumSlots = 64; 27780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 27880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen explicit FastNewContextStub(int slots) : slots_(slots) { 27980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(slots_ > 0 && slots <= kMaximumSlots); 28080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 28180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int slots_; 28680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 28780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "FastNewContextStub"; } 28880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return FastNewContext; } 28980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return slots_; } 29080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 29180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 29280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 29380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass FastCloneShallowArrayStub : public CodeStub { 29480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 29580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Maximum length of copied elements array. 29680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static const int kMaximumClonedLength = 8; 29780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 29880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen enum Mode { 29980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CLONE_ELEMENTS, 30080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen COPY_ON_WRITE_ELEMENTS 30180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 30280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 30380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen FastCloneShallowArrayStub(Mode mode, int length) 30480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : mode_(mode), 30580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) { 30680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(length_ >= 0); 30780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(length_ <= kMaximumClonedLength); 30880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 30980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 31080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 31180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 31280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 31380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Mode mode_; 31480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int length_; 31580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 31680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "FastCloneShallowArrayStub"; } 31780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return FastCloneShallowArray; } 31880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { 31980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(mode_ == 0 || mode_ == 1); 32080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return (length_ << 1) | mode_; 32180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 32280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 32380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass InstanceofStub: public CodeStub { 32680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum Flags { 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kNoFlags = 0, 329086aeeaae12517475c22695a200be45495516549Ben Murdoch kArgsInRegisters = 1 << 0, 330086aeeaae12517475c22695a200be45495516549Ben Murdoch kCallSiteInlineCheck = 1 << 1, 331086aeeaae12517475c22695a200be45495516549Ben Murdoch kReturnTrueFalseObject = 1 << 2 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 334086aeeaae12517475c22695a200be45495516549Ben Murdoch explicit InstanceofStub(Flags flags) : flags_(flags), name_(NULL) { } 335086aeeaae12517475c22695a200be45495516549Ben Murdoch 336086aeeaae12517475c22695a200be45495516549Ben Murdoch static Register left(); 337086aeeaae12517475c22695a200be45495516549Ben Murdoch static Register right(); 33880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 34180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 34280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return Instanceof; } 343086aeeaae12517475c22695a200be45495516549Ben Murdoch int MinorKey() { return static_cast<int>(flags_); } 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 345086aeeaae12517475c22695a200be45495516549Ben Murdoch bool HasArgsInRegisters() const { 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return (flags_ & kArgsInRegisters) != 0; 347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 349086aeeaae12517475c22695a200be45495516549Ben Murdoch bool HasCallSiteInlineCheck() const { 350086aeeaae12517475c22695a200be45495516549Ben Murdoch return (flags_ & kCallSiteInlineCheck) != 0; 351086aeeaae12517475c22695a200be45495516549Ben Murdoch } 352086aeeaae12517475c22695a200be45495516549Ben Murdoch 353086aeeaae12517475c22695a200be45495516549Ben Murdoch bool ReturnTrueFalseObject() const { 354086aeeaae12517475c22695a200be45495516549Ben Murdoch return (flags_ & kReturnTrueFalseObject) != 0; 355086aeeaae12517475c22695a200be45495516549Ben Murdoch } 356086aeeaae12517475c22695a200be45495516549Ben Murdoch 357086aeeaae12517475c22695a200be45495516549Ben Murdoch const char* GetName(); 358086aeeaae12517475c22695a200be45495516549Ben Murdoch 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Flags flags_; 360086aeeaae12517475c22695a200be45495516549Ben Murdoch char* name_; 36180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 36280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 36380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 36480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum NegativeZeroHandling { 36580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen kStrictNegativeZero, 36680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen kIgnoreNegativeZero 36780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 36880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 36980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 3700d5e116f6aee03185f237311a943491bb079a768Kristian Monsenenum UnaryOpFlags { 3710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_UNARY_FLAGS = 0, 3720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_UNARY_SMI_CODE_IN_STUB = 1 << 0 3730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 3740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 3750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 37680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass GenericUnaryOpStub : public CodeStub { 37780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 37880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen GenericUnaryOpStub(Token::Value op, 37980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen UnaryOverwriteMode overwrite, 3800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen UnaryOpFlags flags, 38180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NegativeZeroHandling negative_zero = kStrictNegativeZero) 3820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen : op_(op), 3830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen overwrite_(overwrite), 3840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_smi_code_((flags & NO_UNARY_SMI_CODE_IN_STUB) == 0), 3850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen negative_zero_(negative_zero) { } 38680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 38780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 38880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Token::Value op_; 38980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen UnaryOverwriteMode overwrite_; 3900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool include_smi_code_; 39180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NegativeZeroHandling negative_zero_; 39280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 39380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class OverwriteField: public BitField<UnaryOverwriteMode, 0, 1> {}; 3940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class IncludeSmiCodeField: public BitField<bool, 1, 1> {}; 3950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class NegativeZeroField: public BitField<NegativeZeroHandling, 2, 1> {}; 3960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class OpField: public BitField<Token::Value, 3, kMinorBits - 3> {}; 39780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 39880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return GenericUnaryOp; } 39980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { 40080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return OpField::encode(op_) | 4010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen OverwriteField::encode(overwrite_) | 4020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen IncludeSmiCodeField::encode(include_smi_code_) | 4030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NegativeZeroField::encode(negative_zero_); 40480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 40580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 40680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 40780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 40880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName(); 40980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 41080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 41180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass MathPowStub: public CodeStub { 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MathPowStub() {} 415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate(MacroAssembler* masm); 416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual CodeStub::Major MajorKey() { return MathPow; } 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int MinorKey() { return 0; } 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* GetName() { return "MathPowStub"; } 422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass StringCharAtStub: public CodeStub { 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StringCharAtStub() {} 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Major MajorKey() { return StringCharAt; } 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int MinorKey() { return 0; } 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Generate(MacroAssembler* masm); 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass ICCompareStub: public CodeStub { 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ICCompareStub(Token::Value op, CompareIC::State state) 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : op_(op), state_(state) { 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(Token::IsCompareOp(op)); 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void Generate(MacroAssembler* masm); 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class OpField: public BitField<int, 0, 3> { }; 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch class StateField: public BitField<int, 3, 5> { }; 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void FinishCode(Code* code) { code->set_compare_state(state_); } 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual CodeStub::Major MajorKey() { return CompareIC; } 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int MinorKey(); 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int GetCodeKind() { return Code::COMPARE_IC; } 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateSmis(MacroAssembler* masm); 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateHeapNumbers(MacroAssembler* masm); 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateObjects(MacroAssembler* masm); 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void GenerateMiss(MacroAssembler* masm); 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool strict() const { return op_ == Token::EQ_STRICT; } 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition GetCondition() const { return CompareIC::ComputeCondition(op_); } 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::Value op_; 466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompareIC::State state_; 46780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 46880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 46980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// Flags that control the compare stub code generation. 4710d5e116f6aee03185f237311a943491bb079a768Kristian Monsenenum CompareFlags { 4720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_COMPARE_FLAGS = 0, 4730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_SMI_COMPARE_IN_STUB = 1 << 0, 4740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen NO_NUMBER_COMPARE_IN_STUB = 1 << 1, 4750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CANT_BOTH_BE_NAN = 1 << 2 4760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}; 4770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochenum NaNInformation { 480b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kBothCouldBeNaN, 481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kCantBothBeNaN 482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 48580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass CompareStub: public CodeStub { 48680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 48780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CompareStub(Condition cc, 48880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool strict, 4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompareFlags flags, 4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register lhs, 4910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register rhs) : 492b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cc_(cc), 49380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen strict_(strict), 4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), 4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), 4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), 49780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen lhs_(lhs), 49880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen rhs_(rhs), 49980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen name_(NULL) { } 50080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompareStub(Condition cc, 5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool strict, 5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen CompareFlags flags) : 5040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen cc_(cc), 5050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen strict_(strict), 5060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), 5070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), 5080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), 5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen lhs_(no_reg), 5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen rhs_(no_reg), 5110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen name_(NULL) { } 5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 51380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 51480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 51580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 51680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Condition cc_; 51780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool strict_; 51880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Only used for 'equal' comparisons. Tells the stub that we already know 51980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // that at least one side of the comparison is not NaN. This allows the 52080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // stub to use object identity in the positive case. We ignore it when 52180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // generating the minor key for other comparisons to avoid creating more 52280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // stubs. 52380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool never_nan_nan_; 52480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Do generate the number comparison code in the stub. Stubs without number 52580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // comparison code is used when the number comparison has been inlined, and 52680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // the stub will be called if one of the operands is not a number. 52780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool include_number_compare_; 5280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Generate the comparison code for two smi operands in the stub. 5300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen bool include_smi_compare_; 5310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 53280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Register holding the left hand side of the comparison if the stub gives 53380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // a choice, no_reg otherwise. 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 53580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register lhs_; 53680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Register holding the right hand side of the comparison if the stub gives 53780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // a choice, no_reg otherwise. 53880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register rhs_; 53980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // Encoding of the minor key in 16 bits. 54180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class StrictField: public BitField<bool, 0, 1> {}; 54280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class NeverNanNanField: public BitField<bool, 1, 1> {}; 54380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class IncludeNumberCompareField: public BitField<bool, 2, 1> {}; 5440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class IncludeSmiCompareField: public BitField<bool, 3, 1> {}; 5450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class RegisterField: public BitField<bool, 4, 1> {}; 5460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen class ConditionField: public BitField<int, 5, 11> {}; 54780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 54880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return Compare; } 54980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 55080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey(); 55180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual int GetCodeKind() { return Code::COMPARE_IC; } 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch virtual void FinishCode(Code* code) { 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_compare_state(CompareIC::GENERIC); 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 55780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Branch to the label if the given object isn't a symbol. 55880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void BranchIfNonSymbol(MacroAssembler* masm, 55980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* label, 56080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register object, 56180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch); 56280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 56380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Unfortunately you have to run without snapshots to see most of these 56480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // names in the profile since most compare stubs end up in the snapshot. 56580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen char* name_; 56680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName(); 56780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifdef DEBUG 56880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Print() { 5690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen PrintF("CompareStub (minor %d) (cc %d), (strict %s), " 5700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen "(never_nan_nan %s), (smi_compare %s) (number_compare %s) ", 5710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen MinorKey(), 57280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static_cast<int>(cc_), 57380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen strict_ ? "true" : "false", 57480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen never_nan_nan_ ? "true" : "false", 5750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen include_smi_compare_ ? "inluded" : "not included", 57680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen include_number_compare_ ? "included" : "not included"); 57780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 57880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) { 57980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code()); 58080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 58180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen PrintF("\n"); 58280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 58380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 58480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 58580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 58680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 58780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 58880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass CEntryStub : public CodeStub { 58980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch explicit CEntryStub(int result_size) 591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : result_size_(result_size), save_doubles_(false) { } 59280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 59380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void SaveDoubles() { save_doubles_ = true; } 59580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 59680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 59780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateCore(MacroAssembler* masm, 59880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* throw_normal_exception, 59980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* throw_termination_exception, 60080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* throw_out_of_memory_exception, 60180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool do_gc, 60280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool always_allocate_scope, 60380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int alignment_skew = 0); 60480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateThrowTOS(MacroAssembler* masm); 60580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateThrowUncatchable(MacroAssembler* masm, 60680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen UncatchableExceptionType type); 60780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 60880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Number of pointers/values returned. 60980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const int result_size_; 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool save_doubles_; 61180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 61280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return CEntry; } 61380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey(); 61480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 61580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "CEntryStub"; } 61680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 61780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 61880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 61980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass JSEntryStub : public CodeStub { 62080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 62180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSEntryStub() { } 62280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 62380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm) { GenerateBody(masm, false); } 62480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 62580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen protected: 62680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateBody(MacroAssembler* masm, bool is_construct); 62780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 62880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 62980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return JSEntry; } 63080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 63180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 63280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "JSEntryStub"; } 63380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 63480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 63580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 63680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass JSConstructEntryStub : public JSEntryStub { 63780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 63880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen JSConstructEntryStub() { } 63980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm) { GenerateBody(masm, true); } 64180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 64380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 1; } 64480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "JSConstructEntryStub"; } 64680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 64780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 64980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass ArgumentsAccessStub: public CodeStub { 65080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 65180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen enum Type { 65280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen READ_ELEMENT, 65380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen NEW_OBJECT 65480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen }; 65580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 65680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen explicit ArgumentsAccessStub(Type type) : type_(type) { } 65780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 65880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 65980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Type type_; 66080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return ArgumentsAccess; } 66280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return type_; } 66380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 66580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateReadElement(MacroAssembler* masm); 66680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateNewObject(MacroAssembler* masm); 66780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 66880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "ArgumentsAccessStub"; } 66980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 67080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifdef DEBUG 67180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Print() { 67280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen PrintF("ArgumentsAccessStub (type %d)\n", type_); 67380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 67480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 67580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 67680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 67780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 67880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass RegExpExecStub: public CodeStub { 67980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 68080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RegExpExecStub() { } 68180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 68380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return RegExpExec; } 68480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { return 0; } 68580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 68780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 68880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const char* GetName() { return "RegExpExecStub"; } 68980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 69080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifdef DEBUG 69180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Print() { 69280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen PrintF("RegExpExecStub\n"); 69380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 69480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 69580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 69680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 69780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass RegExpConstructResultStub: public CodeStub { 699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch RegExpConstructResultStub() { } 701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Major MajorKey() { return RegExpConstructResult; } 704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int MinorKey() { return 0; } 705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Generate(MacroAssembler* masm); 707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* GetName() { return "RegExpConstructResultStub"; } 709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void Print() { 712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("RegExpConstructResultStub\n"); 713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 71880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass CallFunctionStub: public CodeStub { 71980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 72080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags) 72180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : argc_(argc), in_loop_(in_loop), flags_(flags) { } 72280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Generate(MacroAssembler* masm); 72480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 725086aeeaae12517475c22695a200be45495516549Ben Murdoch static int ExtractArgcFromMinorKey(int minor_key) { 726086aeeaae12517475c22695a200be45495516549Ben Murdoch return ArgcBits::decode(minor_key); 727086aeeaae12517475c22695a200be45495516549Ben Murdoch } 728086aeeaae12517475c22695a200be45495516549Ben Murdoch 72980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 73080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int argc_; 73180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag in_loop_; 73280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CallFunctionFlags flags_; 73380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 73480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifdef DEBUG 73580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void Print() { 73680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n", 73780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen argc_, 73880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static_cast<int>(in_loop_), 73980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static_cast<int>(flags_)); 74080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 74180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 74280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 74380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. 74480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class InLoopBits: public BitField<InLoopFlag, 0, 1> {}; 74580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class FlagBits: public BitField<CallFunctionFlags, 1, 1> {}; 74680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen class ArgcBits: public BitField<int, 2, 32 - 2> {}; 74780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 74880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Major MajorKey() { return CallFunction; } 74980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int MinorKey() { 75080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Encode the parameters in a unique 32 bit value. 75180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return InLoopBits::encode(in_loop_) 75280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen | FlagBits::encode(flags_) 75380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen | ArgcBits::encode(argc_); 75480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 75580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 75680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InLoopFlag InLoop() { return in_loop_; } 75780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen bool ReceiverMightBeValue() { 75880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return (flags_ & RECEIVER_MIGHT_BE_VALUE) != 0; 75980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 76080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 76180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 76280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 76380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenenum StringIndexFlags { 76480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Accepts smis or heap numbers. 76580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen STRING_INDEX_IS_NUMBER, 76680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 76780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Accepts smis or heap numbers that are valid array indices 76880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // (ECMA-262 15.4). Invalid indices are reported as being out of 76980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // range. 77080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen STRING_INDEX_IS_ARRAY_INDEX 77180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 77280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 77380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 77480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Generates code implementing String.prototype.charCodeAt. 77580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 77680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Only supports the case when the receiver is a string and the index 77780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// is a number (smi or heap number) that is a valid index into the 77880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// string. Additional index constraints are specified by the 77980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// flags. Otherwise, bails out to the provided labels. 78080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 78180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Register usage: |object| may be changed to another string in a way 78280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// that doesn't affect charCodeAt/charAt semantics, |index| is 78380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// preserved, |scratch| and |result| are clobbered. 78480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCharCodeAtGenerator { 78580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 78680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharCodeAtGenerator(Register object, 78780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register index, 78880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch, 78980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result, 79080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* receiver_not_string, 79180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_not_number, 79280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_out_of_range, 79380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringIndexFlags index_flags) 79480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : object_(object), 79580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_(index), 79680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen scratch_(scratch), 79780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen result_(result), 79880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen receiver_not_string_(receiver_not_string), 79980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_not_number_(index_not_number), 80080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_out_of_range_(index_out_of_range), 80180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_flags_(index_flags) { 80280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!scratch_.is(object_)); 80380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!scratch_.is(index_)); 80480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!scratch_.is(result_)); 80580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!result_.is(object_)); 80680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!result_.is(index_)); 80780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 80880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 80980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the fast case code. On the fallthrough path |result| 81080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // register contains the result. 81180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateFast(MacroAssembler* masm); 81280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 81380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the slow case code. Must not be naturally 81480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reachable. Expected to be put after a ret instruction (e.g., in 81580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // deferred code). Always jumps back to the fast case. 81680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateSlow(MacroAssembler* masm, 81780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const RuntimeCallHelper& call_helper); 81880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 81980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 82080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register object_; 82180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register index_; 82280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch_; 82380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result_; 82480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 82580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* receiver_not_string_; 82680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_not_number_; 82780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_out_of_range_; 82880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 82980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringIndexFlags index_flags_; 83080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 83180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label call_runtime_; 83280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label index_not_smi_; 83380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label got_smi_index_; 83480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label exit_; 83580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 83680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator); 83780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 83880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 83980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 84080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Generates code for creating a one-char string from a char code. 84180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCharFromCodeGenerator { 84280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 84380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharFromCodeGenerator(Register code, 84480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result) 84580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : code_(code), 84680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen result_(result) { 84780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(!code_.is(result_)); 84880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 84980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the fast case code. On the fallthrough path |result| 85180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // register contains the result. 85280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateFast(MacroAssembler* masm); 85380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 85480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the slow case code. Must not be naturally 85580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reachable. Expected to be put after a ret instruction (e.g., in 85680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // deferred code). Always jumps back to the fast case. 85780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateSlow(MacroAssembler* masm, 85880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const RuntimeCallHelper& call_helper); 85980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 86080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 86180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register code_; 86280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result_; 86380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 86480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label slow_case_; 86580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label exit_; 86680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 86780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator); 86880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 86980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 87080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 87180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Generates code implementing String.prototype.charAt. 87280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 87380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Only supports the case when the receiver is a string and the index 87480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// is a number (smi or heap number) that is a valid index into the 87580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// string. Additional index constraints are specified by the 87680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// flags. Otherwise, bails out to the provided labels. 87780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// 87880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Register usage: |object| may be changed to another string in a way 87980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// that doesn't affect charCodeAt/charAt semantics, |index| is 88080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// preserved, |scratch1|, |scratch2|, and |result| are clobbered. 88180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenclass StringCharAtGenerator { 88280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public: 88380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharAtGenerator(Register object, 88480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register index, 88580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch1, 88680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register scratch2, 88780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Register result, 88880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* receiver_not_string, 88980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_not_number, 89080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label* index_out_of_range, 89180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringIndexFlags index_flags) 89280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : char_code_at_generator_(object, 89380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index, 89480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen scratch1, 89580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen scratch2, 89680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen receiver_not_string, 89780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_not_number, 89880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_out_of_range, 89980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen index_flags), 90080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen char_from_code_generator_(scratch2, result) {} 90180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the fast case code. On the fallthrough path |result| 90380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // register contains the result. 90480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateFast(MacroAssembler* masm); 90580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Generates the slow case code. Must not be naturally 90780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reachable. Expected to be put after a ret instruction (e.g., in 90880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // deferred code). Always jumps back to the fast case. 90980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen void GenerateSlow(MacroAssembler* masm, 91080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen const RuntimeCallHelper& call_helper); 91180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 91280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen private: 91380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharCodeAtGenerator char_code_at_generator_; 91480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen StringCharFromCodeGenerator char_from_code_generator_; 91580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 91680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator); 91780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}; 91880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 919086aeeaae12517475c22695a200be45495516549Ben Murdoch 920086aeeaae12517475c22695a200be45495516549Ben Murdochclass AllowStubCallsScope { 921086aeeaae12517475c22695a200be45495516549Ben Murdoch public: 922086aeeaae12517475c22695a200be45495516549Ben Murdoch AllowStubCallsScope(MacroAssembler* masm, bool allow) 923086aeeaae12517475c22695a200be45495516549Ben Murdoch : masm_(masm), previous_allow_(masm->allow_stub_calls()) { 924086aeeaae12517475c22695a200be45495516549Ben Murdoch masm_->set_allow_stub_calls(allow); 925086aeeaae12517475c22695a200be45495516549Ben Murdoch } 926086aeeaae12517475c22695a200be45495516549Ben Murdoch ~AllowStubCallsScope() { 927086aeeaae12517475c22695a200be45495516549Ben Murdoch masm_->set_allow_stub_calls(previous_allow_); 928086aeeaae12517475c22695a200be45495516549Ben Murdoch } 929086aeeaae12517475c22695a200be45495516549Ben Murdoch 930086aeeaae12517475c22695a200be45495516549Ben Murdoch private: 931086aeeaae12517475c22695a200be45495516549Ben Murdoch MacroAssembler* masm_; 932086aeeaae12517475c22695a200be45495516549Ben Murdoch bool previous_allow_; 933086aeeaae12517475c22695a200be45495516549Ben Murdoch 934086aeeaae12517475c22695a200be45495516549Ben Murdoch DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope); 935086aeeaae12517475c22695a200be45495516549Ben Murdoch}; 936086aeeaae12517475c22695a200be45495516549Ben Murdoch 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_CODE_STUBS_H_ 940