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