1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file.
4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifndef V8_X87_MACRO_ASSEMBLER_X87_H_
6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define V8_X87_MACRO_ASSEMBLER_X87_H_
7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assembler.h"
970f84b889d80940eb3f6deafd85f0934aaff7269weiliang.lin@intel.com#include "src/bailout-reason.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/frames.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/globals.h"
12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 {
14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal {
15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Convenience for platform-independent signatures.  We do not normally
17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// distinguish memory operands from other operands on ia32.
18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgtypedef Operand MemOperand;
19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
2238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgenum PointersToHereCheck {
2338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  kPointersToHereMaybeInteresting,
2438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  kPointersToHereAreAlwaysInteresting
2538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org};
26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum RegisterValueType {
29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  REGISTER_VALUE_IS_SMI,
30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  REGISTER_VALUE_IS_INT32
31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
34d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org#ifdef DEBUG
35d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.orgbool AreAliased(Register reg1,
36d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg2,
37d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg3 = no_reg,
38d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg4 = no_reg,
39d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg5 = no_reg,
40d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg6 = no_reg,
41d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg7 = no_reg,
42d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org                Register reg8 = no_reg);
43d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org#endif
44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// MacroAssembler implements a collection of frequently used macros.
47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass MacroAssembler: public Assembler {
48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public:
49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The isolate parameter can be NULL if the macro assembler should
50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // not use isolate-dependent functionality. In this case, it's the
51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // responsibility of the caller to never invoke such function on the
52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // macro assembler.
53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  MacroAssembler(Isolate* isolate, void* buffer, int size);
54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Load(Register dst, const Operand& src, Representation r);
56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Store(Register src, const Operand& dst, Representation r);
57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Operations on roots in the root-array.
59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadRoot(Register destination, Heap::RootListIndex index);
60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void StoreRoot(Register source, Register scratch, Heap::RootListIndex index);
61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CompareRoot(Register with, Register scratch, Heap::RootListIndex index);
62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // These methods can only be used with constant roots (i.e. non-writable
63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // and not in new space).
64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CompareRoot(Register with, Heap::RootListIndex index);
65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CompareRoot(const Operand& with, Heap::RootListIndex index);
66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // GC Support
69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  enum RememberedSetFinalAction {
70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kReturnAtEnd,
71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kFallThroughAtEnd
72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  };
73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Record in the remembered set the fact that we have a pointer to new space
75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // at the address pointed to by the addr register.  Only works if addr is not
76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // in new space.
77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void RememberedSetHelper(Register object,  // Used for debug code.
7806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                           Register addr, Register scratch,
7906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                           SaveFPRegsMode save_fp,
80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           RememberedSetFinalAction and_then);
81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckPageFlag(Register object,
83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     Register scratch,
84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     int mask,
85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     Condition cc,
86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     Label* condition_met,
87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     Label::Distance condition_met_distance = Label::kFar);
88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckPageFlagForMap(
90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Handle<Map> map,
91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      int mask,
92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Condition cc,
93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Label* condition_met,
94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Label::Distance condition_met_distance = Label::kFar);
95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckMapDeprecated(Handle<Map> map,
97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register scratch,
98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Label* if_deprecated);
99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if object is in new space.  Jumps if the object is not in new space.
101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The register scratch can be object itself, but scratch will be clobbered.
102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpIfNotInNewSpace(Register object,
103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           Register scratch,
104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           Label* branch,
105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           Label::Distance distance = Label::kFar) {
106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    InNewSpace(object, scratch, zero, branch, distance);
107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if object is in new space.  Jumps if the object is in new space.
110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The register scratch can be object itself, but it will be clobbered.
111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpIfInNewSpace(Register object,
112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Register scratch,
113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Label* branch,
114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Label::Distance distance = Label::kFar) {
115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    InNewSpace(object, scratch, not_zero, branch, distance);
116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if an object has a given incremental marking color.  Also uses ecx!
119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void HasColor(Register object,
120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register scratch0,
121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register scratch1,
122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Label* has_color,
123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Label::Distance has_color_distance,
124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                int first_bit,
125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                int second_bit);
126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpIfBlack(Register object,
128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Register scratch0,
129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Register scratch1,
130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Label* on_black,
131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Label::Distance on_black_distance = Label::kFar);
132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Checks the color of an object.  If the object is already grey or black
134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // then we just fall through, since it is already live.  If it is white and
135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // we can determine that it doesn't need to be scanned, then we just mark it
136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // black and fall through.  For the rest we jump to the label so the
137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // incremental marker can fix its assumptions.
138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void EnsureNotWhite(Register object,
139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Register scratch1,
140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Register scratch2,
141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Label* object_is_white_and_not_data,
142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Label::Distance distance);
143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Notify the garbage collector that we wrote a pointer into an object.
145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // |object| is the object being stored into, |value| is the object being
146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // stored.  value and scratch registers are clobbered by the operation.
147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The offset is the offset from the start of the object, not the offset from
148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void RecordWriteField(
15006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Register object, int offset, Register value, Register scratch,
15106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      SaveFPRegsMode save_fp,
152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
15338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
15438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
15538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org          kPointersToHereMaybeInteresting);
156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // As above, but the offset has the tag presubtracted.  For use with
158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Operand(reg, off).
159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void RecordWriteContextSlot(
16006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Register context, int offset, Register value, Register scratch,
16106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      SaveFPRegsMode save_fp,
162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
16338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
16438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
16538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org          kPointersToHereMaybeInteresting) {
16606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp,
16706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                     remembered_set_action, smi_check,
16838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org                     pointers_to_here_check_for_value);
169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Notify the garbage collector that we wrote a pointer into a fixed array.
172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // |array| is the array being stored into, |value| is the
173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // object being stored.  |index| is the array index represented as a
174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Smi. All registers are clobbered by the operation RecordWriteArray
175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // filters out smis so it does not update the write barrier if the
176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // value is a smi.
177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void RecordWriteArray(
17806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Register array, Register value, Register index, SaveFPRegsMode save_fp,
179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
18038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
18138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
18238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org          kPointersToHereMaybeInteresting);
183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // For page containing |object| mark region covering |address|
185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // dirty. |object| is the object being stored into, |value| is the
186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // object being stored. The address and value registers are clobbered by the
187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // operation. RecordWrite filters out smis so it does not update the
188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // write barrier if the value is a smi.
189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void RecordWrite(
19006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Register object, Register address, Register value, SaveFPRegsMode save_fp,
191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
19238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
19338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
19438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org          kPointersToHereMaybeInteresting);
195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // For page containing |object| mark the region covering the object's map
197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // dirty. |object| is the object being stored into, |map| is the Map object
198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // that was stored.
19906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void RecordWriteForMap(Register object, Handle<Map> map, Register scratch1,
20006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                         Register scratch2, SaveFPRegsMode save_fp);
201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Debugger Support
204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void DebugBreak();
206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Generates function and stub prologue code.
208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void StubPrologue();
209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Prologue(bool code_pre_aging);
210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Enter specific kind of exit frame. Expects the number of
212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // arguments in register eax and sets up the number of arguments in
213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register edi and the pointer to the first argument in register
214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // esi.
21506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void EnterExitFrame(bool save_doubles);
216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void EnterApiExitFrame(int argc);
218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Leave the current exit frame. Expects the return value in
220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register eax:edx (untouched) and the pointer to the first
221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // argument in register esi.
22206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void LeaveExitFrame(bool save_doubles);
223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Leave the current exit frame. Expects the return value in
225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register eax (untouched).
226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LeaveApiExitFrame(bool restore_context);
227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Find the function context up the context chain.
229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadContext(Register dst, int context_chain_length);
230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Conditionally load the cached Array transitioned map of type
232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // transitioned_kind from the native context if the map in register
233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // map_in_out is the cached Array map in the native context of
234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // expected_kind.
235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadTransitionedArrayMapConditional(
236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      ElementsKind expected_kind,
237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      ElementsKind transitioned_kind,
238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Register map_in_out,
239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Register scratch,
240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Label* no_map_match);
241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Load the global function with the given index.
243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadGlobalFunction(int index, Register function);
244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Load the initial map from the global function. The registers
246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // function and map can be the same.
247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadGlobalFunctionInitialMap(Register function, Register map);
248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Push and pop the registers that can hold pointers.
250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PushSafepointRegisters() { pushad(); }
251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PopSafepointRegisters() { popad(); }
252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Store the value in register/immediate src in the safepoint
253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register stack slot for register dst.
254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void StoreToSafepointRegisterSlot(Register dst, Register src);
255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void StoreToSafepointRegisterSlot(Register dst, Immediate src);
256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadFromSafepointRegisterSlot(Register dst, Register src);
257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadHeapObject(Register result, Handle<HeapObject> object);
259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CmpHeapObject(Register reg, Handle<HeapObject> object);
260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PushHeapObject(Handle<HeapObject> object);
261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadObject(Register result, Handle<Object> object) {
263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AllowDeferredHandleDereference heap_object_check;
264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    if (object->IsHeapObject()) {
265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      LoadHeapObject(result, Handle<HeapObject>::cast(object));
266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    } else {
267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Move(result, Immediate(object));
268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CmpObject(Register reg, Handle<Object> object) {
272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AllowDeferredHandleDereference heap_object_check;
273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    if (object->IsHeapObject()) {
274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      CmpHeapObject(reg, Handle<HeapObject>::cast(object));
275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    } else {
276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      cmp(reg, Immediate(object));
277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // JavaScript invokes
282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Invoke the JavaScript function code by either calling or jumping.
284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokeCode(Register code,
285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  const ParameterCount& expected,
286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  const ParameterCount& actual,
287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  InvokeFlag flag,
288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  const CallWrapper& call_wrapper) {
289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    InvokeCode(Operand(code), expected, actual, flag, call_wrapper);
290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokeCode(const Operand& code,
293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  const ParameterCount& expected,
294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  const ParameterCount& actual,
295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  InvokeFlag flag,
296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  const CallWrapper& call_wrapper);
297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Invoke the JavaScript function in the given register. Changes the
299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // current context to the context in the function before invoking.
300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokeFunction(Register function,
301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const ParameterCount& actual,
302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      InvokeFlag flag,
303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const CallWrapper& call_wrapper);
304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokeFunction(Register function,
306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const ParameterCount& expected,
307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const ParameterCount& actual,
308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      InvokeFlag flag,
309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const CallWrapper& call_wrapper);
310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokeFunction(Handle<JSFunction> function,
312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const ParameterCount& expected,
313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const ParameterCount& actual,
314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      InvokeFlag flag,
315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const CallWrapper& call_wrapper);
316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Invoke specified builtin JavaScript function. Adds an entry to
318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the unresolved list if the name does not resolve.
319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokeBuiltin(Builtins::JavaScript id,
320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     InvokeFlag flag,
321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     const CallWrapper& call_wrapper = NullCallWrapper());
322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Store the function for the given builtin in the target register.
324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Store the code object for the given builtin in the target register.
327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Expression support
330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Support for constant splitting.
331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool IsUnsafeImmediate(const Immediate& x);
332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SafeMove(Register dst, const Immediate& x);
333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SafePush(const Immediate& x);
334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Compare object type for heap object.
336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Incoming register is heap_object and outgoing register is map.
337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CmpObjectType(Register heap_object, InstanceType type, Register map);
338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Compare instance type for map.
340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CmpInstanceType(Register map, InstanceType type);
341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if a map for a JSObject indicates that the object has fast elements.
343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Jump to the specified label if it does not.
344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckFastElements(Register map,
345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         Label* fail,
346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         Label::Distance distance = Label::kFar);
347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if a map for a JSObject indicates that the object can have both smi
349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // and HeapObject elements.  Jump to the specified label if it does not.
350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckFastObjectElements(Register map,
351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Label* fail,
352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Label::Distance distance = Label::kFar);
353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if a map for a JSObject indicates that the object has fast smi only
355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // elements.  Jump to the specified label if it does not.
356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckFastSmiElements(Register map,
357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Label* fail,
358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Label::Distance distance = Label::kFar);
359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check to see if maybe_number can be stored as a double in
361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // FastDoubleElements. If it can, store it at the index specified by key in
362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the FastDoubleElements array elements, otherwise jump to fail.
363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void StoreNumberToDoubleElements(Register maybe_number,
364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                   Register elements,
365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                   Register key,
366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                   Register scratch,
367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                   Label* fail,
368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                   int offset = 0);
369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Compare an object's map with the specified map.
371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CompareMap(Register obj, Handle<Map> map);
372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if the map of an object is equal to a specified map and branch to
374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // label if not. Skip the smi check if not required (object is known to be a
375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // against maps that are ElementsKind transition maps of the specified map.
377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckMap(Register obj,
378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Handle<Map> map,
379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Label* fail,
380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                SmiCheckType smi_check_type);
381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if the map of an object is equal to a specified map and branch to a
383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // specified target if equal. Skip the smi check if not required (object is
384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // known to be a heap object)
385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void DispatchMap(Register obj,
386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Register unused,
387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Handle<Map> map,
388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   Handle<Code> success,
389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   SmiCheckType smi_check_type);
390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if the object in register heap_object is a string. Afterwards the
392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register map contains the object map and the register instance_type
393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // contains the instance_type. The registers map and instance_type can be the
394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // same in which case it contains the instance type afterwards. Either of the
395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // registers map and instance_type can be the same as heap_object.
396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Condition IsObjectStringType(Register heap_object,
397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register map,
398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register instance_type);
399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if the object in register heap_object is a name. Afterwards the
401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register map contains the object map and the register instance_type
402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // contains the instance_type. The registers map and instance_type can be the
403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // same in which case it contains the instance type afterwards. Either of the
404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // registers map and instance_type can be the same as heap_object.
405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Condition IsObjectNameType(Register heap_object,
406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Register map,
407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Register instance_type);
408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if a heap object's type is in the JSObject range, not including
410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // JSFunction.  The object's map will be loaded in the map register.
411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Any or all of the three registers may be the same.
412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The contents of the scratch register will always be overwritten.
413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void IsObjectJSObjectType(Register heap_object,
414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Register map,
415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Register scratch,
416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Label* fail);
417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The contents of the scratch register will be overwritten.
419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // FCmp is similar to integer cmp, but requires unsigned
422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void FCmp();
42406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void FXamMinusZero();
42506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void FXamSign();
42606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void X87CheckIA();
42706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void X87SetRC(int rc);
42879390123903f4a8b6e973f2d4e3743948b97aeb8weiliang.lin@intel.com  void X87SetFPUCW(int cw);
429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void ClampUint8(Register reg);
43106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void ClampTOSToUint8(Register result_reg);
432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SlowTruncateToI(Register result_reg, Register input_reg,
434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      int offset = HeapNumber::kValueOffset - kHeapObjectTag);
435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TruncateX87TOSToI(Register result_reg);
438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void X87TOSToI(Register result_reg, MinusZeroMode minus_zero_mode,
440b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org      Label* lost_precision, Label* is_nan, Label* minus_zero,
441b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org      Label::Distance dst = Label::kFar);
442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Smi tagging support.
444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SmiTag(Register reg) {
445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    STATIC_ASSERT(kSmiTag == 0);
446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    STATIC_ASSERT(kSmiTagSize == 1);
447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    add(reg, reg);
448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SmiUntag(Register reg) {
450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    sar(reg, kSmiTagSize);
451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Modifies the register even if it does not contain a Smi!
454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SmiUntag(Register reg, Label* is_smi) {
455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    STATIC_ASSERT(kSmiTagSize == 1);
456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    sar(reg, kSmiTagSize);
457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    STATIC_ASSERT(kSmiTag == 0);
458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    j(not_carry, is_smi);
459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadUint32NoSSE2(Register src);
462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Jump the register contains a smi.
464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  inline void JumpIfSmi(Register value,
465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Label* smi_label,
466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Label::Distance distance = Label::kFar) {
467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    test(value, Immediate(kSmiTagMask));
468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    j(zero, smi_label, distance);
469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Jump if the operand is a smi.
471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  inline void JumpIfSmi(Operand value,
472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Label* smi_label,
473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Label::Distance distance = Label::kFar) {
474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    test(value, Immediate(kSmiTagMask));
475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    j(zero, smi_label, distance);
476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Jump if register contain a non-smi.
478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  inline void JumpIfNotSmi(Register value,
479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           Label* not_smi_label,
480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           Label::Distance distance = Label::kFar) {
481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    test(value, Immediate(kSmiTagMask));
482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    j(not_zero, not_smi_label, distance);
483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadInstanceDescriptors(Register map, Register descriptors);
486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void EnumLength(Register dst, Register map);
487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void NumberOfOwnDescriptors(Register dst, Register map);
488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  template<typename Field>
490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void DecodeField(Register reg) {
491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    static const int shift = Field::kShift;
492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    static const int mask = Field::kMask >> Field::kShift;
493e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (shift != 0) {
494e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      sar(reg, shift);
495e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    }
496e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    and_(reg, Immediate(mask));
497e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
498e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
499e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  template<typename Field>
500e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  void DecodeFieldToSmi(Register reg) {
501e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    static const int shift = Field::kShift;
502e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
503e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
504e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    STATIC_ASSERT(kSmiTag == 0);
505e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (shift < kSmiTagSize) {
506e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      shl(reg, kSmiTagSize - shift);
507e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    } else if (shift > kSmiTagSize) {
508e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      sar(reg, shift - kSmiTagSize);
509e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    }
510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    and_(reg, Immediate(mask));
511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Abort execution if argument is not a number, enabled via --debug-code.
514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertNumber(Register object);
515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Abort execution if argument is not a smi, enabled via --debug-code.
517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertSmi(Register object);
518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Abort execution if argument is a smi, enabled via --debug-code.
520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertNotSmi(Register object);
521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Abort execution if argument is not a string, enabled via --debug-code.
523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertString(Register object);
524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Abort execution if argument is not a name, enabled via --debug-code.
526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertName(Register object);
527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Abort execution if argument is not undefined or an AllocationSite, enabled
529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // via --debug-code.
530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertUndefinedOrAllocationSite(Register object);
531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Exception handling
534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Push a new try handler and link it into try handler chain.
536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PushTryHandler(StackHandler::Kind kind, int handler_index);
537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Unlink the stack handler on top of the stack from the try handler chain.
539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PopTryHandler();
540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Throw to the top handler in the try hander chain.
542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Throw(Register value);
543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Throw past all JS frames to the top JS entry frame.
545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void ThrowUncatchable(Register value);
546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Inline caching support
549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Generate code for checking access rights - used for security checks
551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // on access to global objects across environments. The holder register
552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // is left untouched, but the scratch register is clobbered.
553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckAccessGlobalProxy(Register holder_reg,
554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                              Register scratch1,
555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                              Register scratch2,
556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                              Label* miss);
557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void GetNumberHash(Register r0, Register scratch);
559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadFromNumberDictionary(Label* miss,
561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Register elements,
562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Register key,
563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Register r0,
564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Register r1,
565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Register r2,
566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Register result);
567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocation support
571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocate an object in new space or old pointer space. If the given space
573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // is exhausted control continues at the gc_required label. The allocated
574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // object is returned in result and end of the new object is returned in
575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // result_end. The register scratch can be passed as no_reg in which case
576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // an additional object reference will be added to the reloc info. The
577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // returned pointers in result and result_end have not yet been tagged as
578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // heap objects. If result_contains_top_on_entry is true the content of
579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // result is known to be the allocation top on entry (could be result_end
580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // from a previous call). If result_contains_top_on_entry is true scratch
581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // should be no_reg as it is never used.
582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Allocate(int object_size,
583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register result,
584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register result_end,
585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register scratch,
586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Label* gc_required,
587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                AllocationFlags flags);
588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Allocate(int header_size,
590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                ScaleFactor element_size,
591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register element_count,
592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                RegisterValueType element_count_type,
593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register result,
594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register result_end,
595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register scratch,
596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Label* gc_required,
597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                AllocationFlags flags);
598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Allocate(Register object_size,
600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register result,
601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register result_end,
602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Register scratch,
603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                Label* gc_required,
604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                AllocationFlags flags);
605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Undo allocation in new space. The object passed and objects allocated after
607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // it will no longer be allocated. Make sure that no pointers are left to the
608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // object(s) no longer allocated as they would be invalid when allocation is
609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // un-done.
610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void UndoAllocationInNewSpace(Register object);
611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocate a heap number in new space with undefined value. The
613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // register scratch2 can be passed as no_reg; the others must be
614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // valid registers. Returns tagged pointer in result register, or
615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // jumps to gc_required if new space is full.
616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AllocateHeapNumber(Register result,
617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register scratch1,
618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register scratch2,
61958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org                          Label* gc_required,
62058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org                          MutableMode mode = IMMUTABLE);
621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocate a sequential string. All the header fields of the string object
623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // are initialized.
624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AllocateTwoByteString(Register result,
625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Register length,
626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Register scratch1,
627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Register scratch2,
628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Register scratch3,
629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             Label* gc_required);
630b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void AllocateOneByteString(Register result, Register length,
631b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                             Register scratch1, Register scratch2,
632b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                             Register scratch3, Label* gc_required);
633b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void AllocateOneByteString(Register result, int length, Register scratch1,
634b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                             Register scratch2, Label* gc_required);
635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocate a raw cons string object. Only the map field of the result is
637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // initialized.
638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AllocateTwoByteConsString(Register result,
639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register scratch1,
640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register scratch2,
641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Label* gc_required);
642b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void AllocateOneByteConsString(Register result, Register scratch1,
643b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                                 Register scratch2, Label* gc_required);
644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocate a raw sliced string object. Only the map field of the result is
646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // initialized.
647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AllocateTwoByteSlicedString(Register result,
648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Register scratch1,
649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Register scratch2,
650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Label* gc_required);
651b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void AllocateOneByteSlicedString(Register result, Register scratch1,
652b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                                   Register scratch2, Label* gc_required);
653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Copy memory, byte-by-byte, from source to destination.  Not optimized for
655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // long or aligned copies.
656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The contents of index and scratch are destroyed.
657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CopyBytes(Register source,
658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                 Register destination,
659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                 Register length,
660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                 Register scratch);
661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Initialize fields with filler values.  Fields starting at |start_offset|
663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // not including end_offset are overwritten with the value in |filler|.  At
664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the end the loop, |start_offset| takes the value of |end_offset|.
665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InitializeFieldsWithFiller(Register start_offset,
666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                  Register end_offset,
667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                  Register filler);
668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Support functions.
671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check a boolean-bit of a Smi field.
673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void BooleanBitTest(Register object, int field_offset, int bit_index);
674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if result is zero and op is negative.
676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void NegativeZeroTest(Register result, Register op, Label* then_label);
677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check if result is zero and any of op1 and op2 are negative.
679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register scratch is destroyed, and it must be different from op2.
680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void NegativeZeroTest(Register result, Register op1, Register op2,
681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                        Register scratch, Label* then_label);
682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Try to get function prototype of a function and puts the value in
684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the result register. Checks that the function really is a
685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // function and jumps to the miss label if the fast checks fail. The
686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // function register will be untouched; the other registers may be
687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // clobbered.
688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TryGetFunctionPrototype(Register function,
689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register result,
690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register scratch,
691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Label* miss,
692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               bool miss_on_bound_function = false);
693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Picks out an array index from the hash field.
695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register use:
696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //   hash - holds the index's hash. Clobbered.
697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //   index - holds the overwritten index on exit.
698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void IndexFromHash(Register hash, Register index);
699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Runtime calls
702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Call a code stub.  Generate the code if necessary.
704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());
705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Tail call a code stub (jump).  Generate the code if necessary.
707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TailCallStub(CodeStub* stub);
708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Return from a code stub after popping its arguments.
710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void StubReturn(int argc);
711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Call a runtime routine.
71306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void CallRuntime(const Runtime::Function* f, int num_arguments,
71406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
71506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
71706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    CallRuntime(function, function->nargs, kSaveFPRegs);
718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
71906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
72006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  // Convenience function: Same as above, but takes the fid instead.
72106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void CallRuntime(Runtime::FunctionId id, int num_arguments,
72206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
72306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Convenience function: call an external reference.
727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CallExternalReference(ExternalReference ref, int num_arguments);
728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Tail call of a runtime routine (jump).
730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Like JumpToExternalReference, but also takes care of passing the number
731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // of parameters.
732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TailCallExternalReference(const ExternalReference& ext,
733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 int num_arguments,
734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 int result_size);
735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Convenience function: tail call a runtime routine (jump).
737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TailCallRuntime(Runtime::FunctionId fid,
738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       int num_arguments,
739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       int result_size);
740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Before calling a C-function from generated code, align arguments on stack.
742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // After aligning the frame, arguments must be stored in esp[0], esp[4],
743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // etc., not pushed. The argument count assumes all arguments are word sized.
744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Some compilers/platforms require the stack to be aligned when calling
745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // C++ code.
746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Needs a scratch register to do some arithmetic. This register will be
747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // trashed.
748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PrepareCallCFunction(int num_arguments, Register scratch);
749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Calls a C function and cleans up the space for arguments allocated
751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // by PrepareCallCFunction. The called function is not allowed to trigger a
752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // garbage collection, since that might move the code and invalidate the
753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // return address (unless this is somehow accounted for by the called
754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // function).
755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CallCFunction(ExternalReference function, int num_arguments);
756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CallCFunction(Register function, int num_arguments);
757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Prepares stack to put arguments (aligns and so on). Reserves
759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // space for return value if needed (assumes the return value is a handle).
760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // etc. Saves context (esi). If space was reserved for return value then
762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // stores the pointer to the reserved slot into esi.
763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void PrepareCallApiFunction(int argc);
764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Calls an API function.  Allocates HandleScope, extracts returned value
766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // from handle and propagates exceptions.  Clobbers ebx, edi and
767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // caller-save registers.  Restores context.  On return removes
768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // stack_space * kPointerSize (GCed).
769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CallApiFunctionAndReturn(Register function_address,
770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                ExternalReference thunk_ref,
771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Operand thunk_last_arg,
772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                int stack_space,
773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Operand return_value_operand,
774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                Operand* context_restore_operand);
775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Jump to a runtime routine.
777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpToExternalReference(const ExternalReference& ext);
778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Utilities
781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Ret();
783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Return and drop arguments from stack, where the number of arguments
785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // may be bigger than 2^16 - 1.  Requires a scratch register.
786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Ret(int bytes_dropped, Register scratch);
787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Emit code to discard a non-negative number of pointer-sized elements
789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // from the stack, clobbering only the esp register.
790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Drop(int element_count);
791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Call(Label* target) { call(target); }
793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Push(Register src) { push(src); }
794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Pop(Register dst) { pop(dst); }
795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Emit call to the code we are currently generating.
797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CallSelf() {
798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    call(self, RelocInfo::CODE_TARGET);
800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Move if the registers are not identical.
803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Move(Register target, Register source);
804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Move a constant into a destination using the most efficient encoding.
806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Move(Register dst, const Immediate& x);
807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Move(const Operand& dst, const Immediate& x);
808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Push a handle value.
810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Push(Handle<Object> handle) { push(Immediate(handle)); }
811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Handle<Object> CodeObject() {
814e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!code_object_.is_null());
815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return code_object_;
816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Insert code to verify that the x87 stack has the specified depth (0-7)
819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void VerifyX87StackDepth(uint32_t depth);
820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Emit code for a truncating division by a constant. The dividend register is
822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // unchanged, the result is in edx, and eax gets clobbered.
823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TruncatingDiv(Register dividend, int32_t divisor);
824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // StatsCounter support
827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SetCounter(StatsCounter* counter, int value);
829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void IncrementCounter(StatsCounter* counter, int value);
830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void DecrementCounter(StatsCounter* counter, int value);
831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void IncrementCounter(Condition cc, StatsCounter* counter, int value);
832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void DecrementCounter(Condition cc, StatsCounter* counter, int value);
833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Debugging
837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Calls Abort(msg) if the condition cc is not satisfied.
839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Use --debug_code to enable.
840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Assert(Condition cc, BailoutReason reason);
841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AssertFastElements(Register elements);
843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Like Assert(), but always enabled.
845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Check(Condition cc, BailoutReason reason);
846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Print a message to stdout and abort execution.
848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Abort(BailoutReason reason);
849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check that the stack is aligned.
851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckStackAlignment();
852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Verify restrictions about code generated in stubs.
854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void set_generating_stub(bool value) { generating_stub_ = value; }
855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool generating_stub() { return generating_stub_; }
856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void set_has_frame(bool value) { has_frame_ = value; }
857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool has_frame() { return has_frame_; }
858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  inline bool AllowThisStubCall(CodeStub* stub);
859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ---------------------------------------------------------------------------
861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // String utilities.
862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Generate code to do a lookup in the number string cache. If the number in
864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the register object is found in the cache the generated code falls through
865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // with the result in the result register. The object and the result register
866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // can be the same. If the number is not found in the cache the code jumps to
867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the label not_found with only the content of register object unchanged.
868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LookupNumberStringCache(Register object,
869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register result,
870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register scratch1,
871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register scratch2,
872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Label* not_found);
873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
874b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  // Check whether the instance type represents a flat one-byte string. Jump to
875b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  // the label if not. If the instance type can be scratched specify same
876b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  // register for both instance type and scratch.
877b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void JumpIfInstanceTypeIsNotSequentialOneByte(
878b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      Register instance_type, Register scratch,
879b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      Label* on_not_flat_one_byte_string);
880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
881b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  // Checks if both objects are sequential one-byte strings, and jumps to label
882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // if either is not.
883b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void JumpIfNotBothSequentialOneByteStrings(
884b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      Register object1, Register object2, Register scratch1, Register scratch2,
885b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      Label* on_not_flat_one_byte_strings);
886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Checks if the given register or operand is a unique name
88806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name,
88906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                       Label::Distance distance = Label::kFar) {
89006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance);
891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
89306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name,
89406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org                                       Label::Distance distance = Label::kFar);
895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void EmitSeqStringSetCharCheck(Register string,
897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 Register index,
898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 Register value,
899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 uint32_t encoding_mask);
900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  static int SafepointRegisterStackIndex(Register reg) {
902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return SafepointRegisterStackIndex(reg.code());
903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Activation support.
906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void EnterFrame(StackFrame::Type type);
907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LeaveFrame(StackFrame::Type type);
908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Expects object in eax and returns map with validated enum cache
910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // in eax.  Assumes that any other register can be used as a scratch.
911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CheckEnumCache(Label* call_runtime);
912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // AllocationMemento support. Arrays may have an associated
914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // AllocationMemento object that can be checked for in order to pretransition
915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // to another type.
916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // On entry, receiver_reg should point to the array object.
917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // scratch_reg gets clobbered.
918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // If allocation info is present, conditional code is set to equal.
919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void TestJSArrayForAllocationMemento(Register receiver_reg,
920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                       Register scratch_reg,
921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                       Label* no_memento_found);
922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                         Register scratch_reg,
925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                         Label* memento_found) {
926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    Label no_memento_found;
927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                    &no_memento_found);
929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    j(equal, memento_found);
930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    bind(&no_memento_found);
931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Jumps to found label if a prototype map has dictionary elements.
934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                        Register scratch1, Label* found);
936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private:
938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool generating_stub_;
939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool has_frame_;
940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // This handle will be patched with the code object on installation.
941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Handle<Object> code_object_;
942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Helper functions for generating invokes.
944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InvokePrologue(const ParameterCount& expected,
945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const ParameterCount& actual,
946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Handle<Code> code_constant,
947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const Operand& code_operand,
948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Label* done,
949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      bool* definitely_mismatches,
950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      InvokeFlag flag,
951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      Label::Distance done_distance,
952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                      const CallWrapper& call_wrapper = NullCallWrapper());
953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void EnterExitFramePrologue();
95506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void EnterExitFrameEpilogue(int argc, bool save_doubles);
956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LeaveExitFrameEpilogue(bool restore_context);
958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Allocation support helpers.
960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void LoadAllocationTopHelper(Register result,
961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               Register scratch,
962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                               AllocationFlags flags);
963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void UpdateAllocationTopHelper(Register result_end,
965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 Register scratch,
966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 AllocationFlags flags);
967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void InNewSpace(Register object,
970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  Register scratch,
971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  Condition cc,
972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  Label* condition_met,
973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                  Label::Distance condition_met_distance = Label::kFar);
974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Helper for finding the mark bits for an address.  Afterwards, the
976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // bitmap register points at the word with the mark bits and the mask
977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // the position of the first bit.  Uses ecx as scratch and leaves addr_reg
978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // unchanged.
979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  inline void GetMarkBits(Register addr_reg,
980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register bitmap_reg,
981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          Register mask_reg);
982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Helper for throwing exceptions.  Compute a handler address and jump to
984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // it.  See the implementation for register usage.
985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void JumpToHandlerEntry();
986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Compute memory operands for safepoint stack slots.
988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Operand SafepointRegisterSlot(Register reg);
989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  static int SafepointRegisterStackIndex(int reg_code);
990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Needs access to SafepointRegisterStackIndex for compiled frame
992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // traversal.
993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  friend class StandardFrame;
994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for
998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// debugging and other types of instrumentation. When using the code patcher
999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the exact number of bytes specified must be emitted. Is not legal to emit
1000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// relocation information. If any of these constraints are violated it causes
1001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// an assertion.
1002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass CodePatcher {
1003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public:
1004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CodePatcher(byte* address, int size);
1005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  virtual ~CodePatcher();
1006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Macro assembler to emit code.
1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  MacroAssembler* masm() { return &masm_; }
1009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private:
1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte* address_;  // The address of the code being patched.
1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int size_;  // Number of bytes of the expected patch size.
1013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  MacroAssembler masm_;  // Macro assembler used to generate the code.
1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// -----------------------------------------------------------------------------
1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Static helper functions.
1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate an Operand for loading a field from an object.
1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand FieldOperand(Register object, int offset) {
1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return Operand(object, offset - kHeapObjectTag);
1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate an Operand for loading an indexed field from an object.
1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand FieldOperand(Register object,
1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            Register index,
1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            ScaleFactor scale,
1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            int offset) {
1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return Operand(object, index, scale, offset - kHeapObjectTag);
1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand FixedArrayElementOperand(Register array,
1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                        Register index_as_smi,
1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                        int additional_offset = 0) {
1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
1039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand ContextOperand(Register context, int index) {
1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return Operand(context, Context::SlotOffset(index));
1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orginline Operand GlobalObjectOperand() {
1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX);
1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generates an Operand for saving parameters after PrepareCallApiFunction.
1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgOperand ApiParameterOperand(int index);
1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef GENERATED_CODE_COVERAGE
1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgextern void LogGeneratedCodeCoverage(const char* file_line);
1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x
1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define ACCESS_MASM(masm) {                                               \
1063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    byte* ia32_coverage_function =                                        \
1064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
1065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->pushfd();                                                       \
1066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->pushad();                                                       \
1067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));         \
1068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY);         \
1069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->pop(eax);                                                       \
1070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->popad();                                                        \
1071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    masm->popfd();                                                        \
1072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }                                                                       \
1073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  masm->
1074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#else
1075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define ACCESS_MASM(masm) masm->
1076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif
1077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} }  // namespace v8::internal
1080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif  // V8_X87_MACRO_ASSEMBLER_X87_H_
1082