1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_
65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define V8_IA32_MACRO_ASSEMBLER_IA32_H_
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assembler.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/frames.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/globals.h"
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org// Convenience for platform-independent signatures.  We do not normally
160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org// distinguish memory operands from other operands on ia32.
170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgtypedef Operand MemOperand;
180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
19c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
20c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgenum PointersToHereCheck {
22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  kPointersToHereMaybeInteresting,
23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  kPointersToHereAreAlwaysInteresting
24196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org};
25c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
26c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.orgenum RegisterValueType {
284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  REGISTER_VALUE_IS_SMI,
294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  REGISTER_VALUE_IS_INT32
304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org};
314cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
324cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
33c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4);
34c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
35c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// MacroAssembler implements a collection of frequently used macros.
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass MacroAssembler: public Assembler {
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
39c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // The isolate parameter can be NULL if the macro assembler should
40c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // not use isolate-dependent functionality. In this case, it's the
41c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // responsibility of the caller to never invoke such function on the
42c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // macro assembler.
43c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  MacroAssembler(Isolate* isolate, void* buffer, int size);
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void Load(Register dst, const Operand& src, Representation r);
46935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void Store(Register src, const Operand& dst, Representation r);
47935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
48594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // Operations on roots in the root-array.
49594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void LoadRoot(Register destination, Heap::RootListIndex index);
50594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void StoreRoot(Register source, Register scratch, Heap::RootListIndex index);
51594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void CompareRoot(Register with, Register scratch, Heap::RootListIndex index);
52594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // These methods can only be used with constant roots (i.e. non-writable
53594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  // and not in new space).
54594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void CompareRoot(Register with, Heap::RootListIndex index);
55594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void CompareRoot(const Operand& with, Heap::RootListIndex index);
56594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GC Support
59c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  enum RememberedSetFinalAction {
60c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kReturnAtEnd,
61c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kFallThroughAtEnd
62c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
63c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Record in the remembered set the fact that we have a pointer to new space
65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // at the address pointed to by the addr register.  Only works if addr is not
66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // in new space.
67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RememberedSetHelper(Register object,  // Used for debug code.
68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register addr,
69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           SaveFPRegsMode save_fp,
71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           RememberedSetFinalAction and_then);
72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckPageFlag(Register object,
74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Register scratch,
75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int mask,
76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Condition cc,
77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Label* condition_met,
78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Label::Distance condition_met_distance = Label::kFar);
79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
807028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void CheckPageFlagForMap(
817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Handle<Map> map,
827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      int mask,
837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Condition cc,
847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Label* condition_met,
857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Label::Distance condition_met_distance = Label::kFar);
867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
87f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  void CheckMapDeprecated(Handle<Map> map,
88f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Register scratch,
89f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Label* if_deprecated);
90f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
91c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if object is in new space.  Jumps if the object is not in new space.
92c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The register scratch can be object itself, but scratch will be clobbered.
93c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfNotInNewSpace(Register object,
94c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
95c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Label* branch,
96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Label::Distance distance = Label::kFar) {
97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InNewSpace(object, scratch, zero, branch, distance);
98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if object is in new space.  Jumps if the object is in new space.
101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The register scratch can be object itself, but it will be clobbered.
102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfInNewSpace(Register object,
103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Register scratch,
104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label* branch,
105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label::Distance distance = Label::kFar) {
106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InNewSpace(object, scratch, not_zero, branch, distance);
107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
108f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if an object has a given incremental marking color.  Also uses ecx!
110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void HasColor(Register object,
111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Register scratch0,
112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Register scratch1,
113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Label* has_color,
114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Label::Distance has_color_distance,
115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                int first_bit,
116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                int second_bit);
117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfBlack(Register object,
119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Register scratch0,
120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Register scratch1,
121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Label* on_black,
122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Label::Distance on_black_distance = Label::kFar);
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Checks the color of an object.  If the object is already grey or black
125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // then we just fall through, since it is already live.  If it is white and
126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // we can determine that it doesn't need to be scanned, then we just mark it
127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // black and fall through.  For the rest we jump to the label so the
128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // incremental marker can fix its assumptions.
129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EnsureNotWhite(Register object,
130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch1,
131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch2,
132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label* object_is_white_and_not_data,
133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label::Distance distance);
134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Notify the garbage collector that we wrote a pointer into an object.
136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // |object| is the object being stored into, |value| is the object being
137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // stored.  value and scratch registers are clobbered by the operation.
138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The offset is the offset from the start of the object, not the offset from
139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteField(
141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register object,
142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int offset,
143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register scratch,
145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
147196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
148196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
149196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting);
150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // As above, but the offset has the tag presubtracted.  For use with
152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Operand(reg, off).
153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteContextSlot(
154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register context,
155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int offset,
156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register scratch,
158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
160196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
161196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
162196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting) {
163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RecordWriteField(context,
164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     offset + kHeapObjectTag,
165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     value,
166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     scratch,
167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     save_fp,
168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     remembered_set_action,
169196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                     smi_check,
170196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                     pointers_to_here_check_for_value);
171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
172f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Notify the garbage collector that we wrote a pointer into a fixed array.
174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // |array| is the array being stored into, |value| is the
175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object being stored.  |index| is the array index represented as a
176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Smi. All registers are clobbered by the operation RecordWriteArray
17769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // filters out smis so it does not update the write barrier if the
17869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // value is a smi.
179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteArray(
180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register array,
181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register index,
183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
185196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
186196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
187196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting);
18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // For page containing |object| mark region covering |address|
19069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // dirty. |object| is the object being stored into, |value| is the
191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object being stored. The address and value registers are clobbered by the
19269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // operation. RecordWrite filters out smis so it does not update the
19369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // write barrier if the value is a smi.
194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWrite(
195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register object,
196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register address,
197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
200196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
201196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
202196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting);
20369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
2047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // For page containing |object| mark the region covering the object's map
2057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // dirty. |object| is the object being stored into, |map| is the Map object
2067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // that was stored.
2077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void RecordWriteForMap(
2087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Register object,
2097028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Handle<Map> map,
2107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Register scratch1,
2117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      Register scratch2,
2127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      SaveFPRegsMode save_fp);
2137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugger Support
21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2175c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DebugBreak();
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
219c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // Generates function and stub prologue code.
220285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  void StubPrologue();
221285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  void Prologue(bool code_pre_aging);
222c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Enter specific kind of exit frame. Expects the number of
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // arguments in register eax and sets up the number of arguments in
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // register edi and the pointer to the first argument in register
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // esi.
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void EnterExitFrame(bool save_doubles);
228c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
2294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  void EnterApiExitFrame(int argc);
230236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
231236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // Leave the current exit frame. Expects the return value in
232236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // register eax:edx (untouched) and the pointer to the first
233236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // argument in register esi.
234a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void LeaveExitFrame(bool save_doubles);
23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2364a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Leave the current exit frame. Expects the return value in
2374a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // register eax (untouched).
238528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LeaveApiExitFrame(bool restore_context);
2394a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
240ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Find the function context up the context chain.
241ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void LoadContext(Register dst, int context_chain_length);
24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2431145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Conditionally load the cached Array transitioned map of type
24446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // transitioned_kind from the native context if the map in register
24546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // map_in_out is the cached Array map in the native context of
2461145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // expected_kind.
2471145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  void LoadTransitionedArrayMapConditional(
2481145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      ElementsKind expected_kind,
2491145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      ElementsKind transitioned_kind,
2501145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Register map_in_out,
2511145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Register scratch,
2521145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Label* no_map_match);
2531145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
254d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Load the global function with the given index.
255d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void LoadGlobalFunction(int index, Register function);
256d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
257d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Load the initial map from the global function. The registers
258d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // function and map can be the same.
259d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void LoadGlobalFunctionInitialMap(Register function, Register map);
260d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Push and pop the registers that can hold pointers.
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PushSafepointRegisters() { pushad(); }
263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PopSafepointRegisters() { popad(); }
2643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Store the value in register/immediate src in the safepoint
2653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // register stack slot for register dst.
2663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void StoreToSafepointRegisterSlot(Register dst, Register src);
2673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void StoreToSafepointRegisterSlot(Register dst, Immediate src);
2683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void LoadFromSafepointRegisterSlot(Register dst, Register src);
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void LoadHeapObject(Register result, Handle<HeapObject> object);
271a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  void CmpHeapObject(Register reg, Handle<HeapObject> object);
27264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void PushHeapObject(Handle<HeapObject> object);
27364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
274bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org  void LoadObject(Register result, Handle<Object> object) {
27579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference heap_object_check;
276bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org    if (object->IsHeapObject()) {
277bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org      LoadHeapObject(result, Handle<HeapObject>::cast(object));
278bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org    } else {
279a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      Move(result, Immediate(object));
280bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org    }
281bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org  }
282bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org
283a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  void CmpObject(Register reg, Handle<Object> object) {
28479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference heap_object_check;
285a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (object->IsHeapObject()) {
286a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      CmpHeapObject(reg, Handle<HeapObject>::cast(object));
287a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    } else {
288a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      cmp(reg, Immediate(object));
289a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
290a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
291a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // JavaScript invokes
29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Invoke the JavaScript function code by either calling or jumping.
296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InvokeCode(Register code,
297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  const ParameterCount& expected,
298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  const ParameterCount& actual,
299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  InvokeFlag flag,
300e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                  const CallWrapper& call_wrapper) {
301e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    InvokeCode(Operand(code), expected, actual, flag, call_wrapper);
302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void InvokeCode(const Operand& code,
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                  const ParameterCount& expected,
30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                  const ParameterCount& actual,
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                  InvokeFlag flag,
308e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                  const CallWrapper& call_wrapper);
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Invoke the JavaScript function in the given register. Changes the
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // current context to the context in the function before invoking.
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void InvokeFunction(Register function,
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      const ParameterCount& actual,
314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                      InvokeFlag flag,
315e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3178a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  void InvokeFunction(Register function,
3188a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const ParameterCount& expected,
3198a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const ParameterCount& actual,
3208a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      InvokeFlag flag,
321e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
3228a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void InvokeFunction(Handle<JSFunction> function,
32432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                      const ParameterCount& expected,
3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org                      const ParameterCount& actual,
326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                      InvokeFlag flag,
327e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
3285c838251403b0be9a882540f1922577abba4c872ager@chromium.org
32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Invoke specified builtin JavaScript function. Adds an entry to
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the unresolved list if the name does not resolve.
331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InvokeBuiltin(Builtins::JavaScript id,
332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                     InvokeFlag flag,
333fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                     const CallWrapper& call_wrapper = NullCallWrapper());
33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
335145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  // Store the function for the given builtin in the target register.
336145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
337145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Store the code object for the given builtin in the target register.
33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Expression support
342528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // cvtsi2sd instruction only writes to the low 64-bit of dst register, which
343528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // hinders register renaming and makes dependence chains longer. So we use
344528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // xorps to clear the dst register before cvtsi2sd to solve this issue.
345528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Cvtsi2sd(XMMRegister dst, Register src) { Cvtsi2sd(dst, Operand(src)); }
346528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Cvtsi2sd(XMMRegister dst, const Operand& src);
347528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
3487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Support for constant splitting.
3497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  bool IsUnsafeImmediate(const Immediate& x);
350a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  void SafeMove(Register dst, const Immediate& x);
3517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void SafePush(const Immediate& x);
3527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
3537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // Compare object type for heap object.
3547be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // Incoming register is heap_object and outgoing register is map.
3557be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void CmpObjectType(Register heap_object, InstanceType type, Register map);
3567be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
3577be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  // Compare instance type for map.
3587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void CmpInstanceType(Register map, InstanceType type);
3597be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
360d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast elements.
361d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Jump to the specified label if it does not.
362d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void CheckFastElements(Register map,
363d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Label* fail,
364d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Label::Distance distance = Label::kFar);
365d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if a map for a JSObject indicates that the object can have both smi
367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // and HeapObject elements.  Jump to the specified label if it does not.
368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckFastObjectElements(Register map,
369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Label* fail,
370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Label::Distance distance = Label::kFar);
371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast smi only
373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // elements.  Jump to the specified label if it does not.
374830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  void CheckFastSmiElements(Register map,
375830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Label* fail,
376830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Label::Distance distance = Label::kFar);
377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check to see if maybe_number can be stored as a double in
379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // FastDoubleElements. If it can, store it at the index specified by key in
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the FastDoubleElements array elements, otherwise jump to fail.
381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void StoreNumberToDoubleElements(Register maybe_number,
382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   Register elements,
383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   Register key,
384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   Register scratch1,
385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   XMMRegister scratch2,
386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   Label* fail,
387fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                   int offset = 0);
388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
389935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  // Compare an object's map with the specified map.
390935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void CompareMap(Register obj, Handle<Map> map);
391f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
392ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Check if the map of an object is equal to a specified map and branch to
393ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // label if not. Skip the smi check if not required (object is known to be a
394f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
3952efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // against maps that are ElementsKind transition maps of the specified map.
3965c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void CheckMap(Register obj,
3975c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Handle<Map> map,
3985c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Label* fail,
399a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                SmiCheckType smi_check_type);
4005c838251403b0be9a882540f1922577abba4c872ager@chromium.org
401ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Check if the map of an object is equal to a specified map and branch to a
402ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // specified target if equal. Skip the smi check if not required (object is
403ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // known to be a heap object)
404ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  void DispatchMap(Register obj,
4052bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                   Register unused,
406ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<Map> map,
407ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<Code> success,
408ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   SmiCheckType smi_check_type);
409ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
4100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Check if the object in register heap_object is a string. Afterwards the
4110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // register map contains the object map and the register instance_type
4120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // contains the instance_type. The registers map and instance_type can be the
4130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // same in which case it contains the instance type afterwards. Either of the
4140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // registers map and instance_type can be the same as heap_object.
4150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  Condition IsObjectStringType(Register heap_object,
4160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                               Register map,
4170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                               Register instance_type);
4180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
419750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Check if the object in register heap_object is a name. Afterwards the
420750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // register map contains the object map and the register instance_type
421750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // contains the instance_type. The registers map and instance_type can be the
422750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // same in which case it contains the instance type afterwards. Either of the
423750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // registers map and instance_type can be the same as heap_object.
424750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Condition IsObjectNameType(Register heap_object,
425750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                             Register map,
426750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                             Register instance_type);
427750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4281af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Check if a heap object's type is in the JSObject range, not including
4291af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // JSFunction.  The object's map will be loaded in the map register.
4301af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Any or all of the three registers may be the same.
4311af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // The contents of the scratch register will always be overwritten.
4321af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void IsObjectJSObjectType(Register heap_object,
4331af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org                            Register map,
4341af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org                            Register scratch,
4351af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org                            Label* fail);
4361af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
4371af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // The contents of the scratch register will be overwritten.
4381af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
4391af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // FCmp is similar to integer cmp, but requires unsigned
44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void FCmp();
44343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
444c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  void ClampUint8(Register reg);
445c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
446c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  void ClampDoubleToUint8(XMMRegister input_reg,
447c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org                          XMMRegister scratch_reg,
448c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org                          Register result_reg);
449c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
4508fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  void SlowTruncateToI(Register result_reg, Register input_reg,
4518fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      int offset = HeapNumber::kValueOffset - kHeapObjectTag);
4528fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
4538fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
4548fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  void TruncateDoubleToI(Register result_reg, XMMRegister input_reg);
4558fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
4568fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  void DoubleToI(Register result_reg, XMMRegister input_reg,
4578fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      XMMRegister scratch, MinusZeroMode minus_zero_mode,
4588fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      Label* conversion_failed, Label::Distance dst = Label::kFar);
4598fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
4608fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  void TaggedToI(Register result_reg, Register input_reg, XMMRegister temp,
4618fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      MinusZeroMode minus_zero_mode, Label* lost_precision);
462c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
4630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Smi tagging support.
4640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void SmiTag(Register reg) {
46580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    STATIC_ASSERT(kSmiTag == 0);
46680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    STATIC_ASSERT(kSmiTagSize == 1);
467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    add(reg, reg);
4680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
4690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void SmiUntag(Register reg) {
4700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    sar(reg, kSmiTagSize);
4710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
4720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
47326c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  // Modifies the register even if it does not contain a Smi!
47426c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  void SmiUntag(Register reg, Label* is_smi) {
47580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    STATIC_ASSERT(kSmiTagSize == 1);
47626c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org    sar(reg, kSmiTagSize);
47780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org    STATIC_ASSERT(kSmiTag == 0);
47826c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org    j(not_carry, is_smi);
47926c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org  }
48026c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org
4817e6132b924829c353864933f29124419916db550machenbach@chromium.org  void LoadUint32(XMMRegister dst, Register src);
48246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
48383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // Jump the register contains a smi.
4847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  inline void JumpIfSmi(Register value,
4857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                        Label* smi_label,
4867b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                        Label::Distance distance = Label::kFar) {
48783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    test(value, Immediate(kSmiTagMask));
4887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    j(zero, smi_label, distance);
4897b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
4907b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  // Jump if the operand is a smi.
4917b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  inline void JumpIfSmi(Operand value,
4927b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                        Label* smi_label,
4937b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                        Label::Distance distance = Label::kFar) {
4947b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    test(value, Immediate(kSmiTagMask));
4957b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    j(zero, smi_label, distance);
49683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
49783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // Jump if register contain a non-smi.
4987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  inline void JumpIfNotSmi(Register value,
4997b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                           Label* not_smi_label,
5007b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org                           Label::Distance distance = Label::kFar) {
50183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    test(value, Immediate(kSmiTagMask));
5027b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    j(not_zero, not_smi_label, distance);
50383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
50483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
50540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void LoadInstanceDescriptors(Register map, Register descriptors);
506355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  void EnumLength(Register dst, Register map);
50706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  void NumberOfOwnDescriptors(Register dst, Register map);
508355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
509355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  template<typename Field>
510355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  void DecodeField(Register reg) {
51106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    static const int shift = Field::kShift;
5123c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org    static const int mask = Field::kMask >> Field::kShift;
513d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (shift != 0) {
514d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      sar(reg, shift);
515d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    }
51606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    and_(reg, Immediate(mask));
517355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
518d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org
519d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  template<typename Field>
520d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  void DecodeFieldToSmi(Register reg) {
521d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    static const int shift = Field::kShift;
522d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
523d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
524d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    STATIC_ASSERT(kSmiTag == 0);
525d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (shift < kSmiTagSize) {
526d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      shl(reg, kSmiTagSize - shift);
527d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    } else if (shift > kSmiTagSize) {
528d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      sar(reg, shift - kSmiTagSize);
529d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    }
530d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    and_(reg, Immediate(mask));
531d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  }
532d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org
533c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
534c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
535c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a number, enabled via --debug-code.
536c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertNumber(Register object);
5375c838251403b0be9a882540f1922577abba4c872ager@chromium.org
538c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a smi, enabled via --debug-code.
539c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertSmi(Register object);
540f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
541c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is a smi, enabled via --debug-code.
542c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertNotSmi(Register object);
54326c16f8ef35ec25d36420512a4ceaa74ea2e2b05vegorov@chromium.org
544c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a string, enabled via --debug-code.
545c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertString(Register object);
546d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
547750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Abort execution if argument is not a name, enabled via --debug-code.
548750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void AssertName(Register object);
549750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
5502904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // Abort execution if argument is not undefined or an AllocationSite, enabled
5512904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // via --debug-code.
5522904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  void AssertUndefinedOrAllocationSite(Register object);
5532904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Exception handling
55643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Push a new try handler and link it into try handler chain.
55878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void PushTryHandler(StackHandler::Kind kind, int handler_index);
55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Unlink the stack handler on top of the stack from the try handler chain.
56113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void PopTryHandler();
56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  // Throw to the top handler in the try hander chain.
56449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void Throw(Register value);
56549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
56665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  // Throw past all JS frames to the top JS entry frame.
56765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  void ThrowUncatchable(Register value);
56849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Inline caching support
57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Generate code for checking access rights - used for security checks
57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // on access to global objects across environments. The holder register
57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is left untouched, but the scratch register is clobbered.
5755a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  void CheckAccessGlobalProxy(Register holder_reg,
576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                              Register scratch1,
577e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                              Register scratch2,
5785a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              Label* miss);
57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
580f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void GetNumberHash(Register r0, Register scratch);
58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void LoadFromNumberDictionary(Label* miss,
5836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register elements,
5846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register key,
5856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register r0,
5866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register r1,
5876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register r2,
5886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register result);
5896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
5906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
59218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Allocation support
59318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
5942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Allocate an object in new space or old pointer space. If the given space
5952bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // is exhausted control continues at the gc_required label. The allocated
5962bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // object is returned in result and end of the new object is returned in
5972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // result_end. The register scratch can be passed as no_reg in which case
5982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // an additional object reference will be added to the reloc info. The
5992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // returned pointers in result and result_end have not yet been tagged as
6002bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // heap objects. If result_contains_top_on_entry is true the content of
6012bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // result is known to be the allocation top on entry (could be result_end
6022bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // from a previous call). If result_contains_top_on_entry is true scratch
60318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // should be no_reg as it is never used.
6042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  void Allocate(int object_size,
6052bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register result,
6062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register result_end,
6072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register scratch,
6082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Label* gc_required,
6092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                AllocationFlags flags);
610c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
611f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  void Allocate(int header_size,
612f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                ScaleFactor element_size,
613f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register element_count,
614f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                RegisterValueType element_count_type,
615f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result,
616f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result_end,
617f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch,
618f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Label* gc_required,
619f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                AllocationFlags flags);
620f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
621f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  void Allocate(Register object_size,
622f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result,
623f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result_end,
624f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch,
625f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Label* gc_required,
626f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                AllocationFlags flags);
62718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
62818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Undo allocation in new space. The object passed and objects allocated after
62918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // it will no longer be allocated. Make sure that no pointers are left to the
63018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // object(s) no longer allocated as they would be invalid when allocation is
63118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // un-done.
63218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void UndoAllocationInNewSpace(Register object);
63318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
6343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Allocate a heap number in new space with undefined value. The
6353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // register scratch2 can be passed as no_reg; the others must be
6363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // valid registers. Returns tagged pointer in result register, or
6373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // jumps to gc_required if new space is full.
6383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void AllocateHeapNumber(Register result,
6393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                          Register scratch1,
6403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                          Register scratch2,
6413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                          Label* gc_required);
6423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
643ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Allocate a sequential string. All the header fields of the string object
644ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // are initialized.
645ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void AllocateTwoByteString(Register result,
646ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                             Register length,
647ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                             Register scratch1,
648ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                             Register scratch2,
649ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                             Register scratch3,
650ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                             Label* gc_required);
651ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void AllocateAsciiString(Register result,
652ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                           Register length,
653ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                           Register scratch1,
654ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                           Register scratch2,
655ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                           Register scratch3,
656ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                           Label* gc_required);
6573cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org  void AllocateAsciiString(Register result,
6583cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org                           int length,
6593cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org                           Register scratch1,
6603cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org                           Register scratch2,
6613cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org                           Label* gc_required);
662ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
663ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Allocate a raw cons string object. Only the map field of the result is
664ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // initialized.
6651805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateTwoByteConsString(Register result,
666ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                          Register scratch1,
667ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                          Register scratch2,
668ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                          Label* gc_required);
669ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void AllocateAsciiConsString(Register result,
670ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                               Register scratch1,
671ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                               Register scratch2,
672ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org                               Label* gc_required);
673ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
67480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // Allocate a raw sliced string object. Only the map field of the result is
67580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  // initialized.
6761805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateTwoByteSlicedString(Register result,
67780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                            Register scratch1,
67880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                            Register scratch2,
67980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                            Label* gc_required);
68080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org  void AllocateAsciiSlicedString(Register result,
68180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                 Register scratch1,
68280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                 Register scratch2,
68380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org                                 Label* gc_required);
68480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org
685c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Copy memory, byte-by-byte, from source to destination.  Not optimized for
686c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // long or aligned copies.
687c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // The contents of index and scratch are destroyed.
688c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void CopyBytes(Register source,
689c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                 Register destination,
690c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                 Register length,
691c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                 Register scratch);
69221b5e95db1c650dfc2ba8e11d010bb01293f85c5vegorov@chromium.org
693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Initialize fields with filler values.  Fields starting at |start_offset|
694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // not including end_offset are overwritten with the value in |filler|.  At
695c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the end the loop, |start_offset| takes the value of |end_offset|.
696c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InitializeFieldsWithFiller(Register start_offset,
697c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  Register end_offset,
698c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  Register filler);
699c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
70018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // ---------------------------------------------------------------------------
70143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Support functions.
70243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
703394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Check a boolean-bit of a Smi field.
704394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void BooleanBitTest(Register object, int field_offset, int bit_index);
705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
70643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if result is zero and op is negative.
70743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void NegativeZeroTest(Register result, Register op, Label* then_label);
70843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check if result is zero and any of op1 and op2 are negative.
71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Register scratch is destroyed, and it must be different from op2.
71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void NegativeZeroTest(Register result, Register op1, Register op2,
71243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                        Register scratch, Label* then_label);
71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7147c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // Try to get function prototype of a function and puts the value in
7157c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // the result register. Checks that the function really is a
7167c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // function and jumps to the miss label if the fast checks fail. The
7177c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // function register will be untouched; the other registers may be
7187c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  // clobbered.
7197c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org  void TryGetFunctionPrototype(Register function,
7207c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                               Register result,
7217c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org                               Register scratch,
722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               Label* miss,
723394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               bool miss_on_bound_function = false);
7247c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
725d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Picks out an array index from the hash field.
726d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Register use:
727d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  //   hash - holds the index's hash. Clobbered.
728d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  //   index - holds the overwritten index on exit.
729d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void IndexFromHash(Register hash, Register index);
730d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Runtime calls
73343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Call a code stub.  Generate the code if necessary.
735471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());
73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
73713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Tail call a code stub (jump).  Generate the code if necessary.
738ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void TailCallStub(CodeStub* stub);
739ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
74043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Return from a code stub after popping its arguments.
74143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void StubReturn(int argc);
74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
74343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call a runtime routine.
744fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void CallRuntime(const Runtime::Function* f,
745fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   int num_arguments,
746fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
747fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
748fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
749fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    CallRuntime(function, function->nargs, kSaveFPRegs);
750fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
75143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convenience function: Same as above, but takes the fid instead.
753f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void CallRuntime(Runtime::FunctionId id,
754f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                   int num_arguments,
755f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
756f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
757fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
75843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
759e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  // Convenience function: call an external reference.
760e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  void CallExternalReference(ExternalReference ref, int num_arguments);
761e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Tail call of a runtime routine (jump).
763ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Like JumpToExternalReference, but also takes care of passing the number
764ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // of parameters.
765ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallExternalReference(const ExternalReference& ext,
766ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int num_arguments,
767ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int result_size);
768ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
769ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Convenience function: tail call a runtime routine (jump).
770ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallRuntime(Runtime::FunctionId fid,
771a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                       int num_arguments,
772a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                       int result_size);
77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
774ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Before calling a C-function from generated code, align arguments on stack.
775ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // After aligning the frame, arguments must be stored in esp[0], esp[4],
776ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // etc., not pushed. The argument count assumes all arguments are word sized.
777ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Some compilers/platforms require the stack to be aligned when calling
778ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // C++ code.
779ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Needs a scratch register to do some arithmetic. This register will be
780ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // trashed.
781ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void PrepareCallCFunction(int num_arguments, Register scratch);
782ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
783ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Calls a C function and cleans up the space for arguments allocated
784ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // by PrepareCallCFunction. The called function is not allowed to trigger a
785ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // garbage collection, since that might move the code and invalidate the
786ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // return address (unless this is somehow accounted for by the called
787ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // function).
788ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void CallCFunction(ExternalReference function, int num_arguments);
789ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void CallCFunction(Register function, int num_arguments);
790ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
791303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // Prepares stack to put arguments (aligns and so on). Reserves
792303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  // space for return value if needed (assumes the return value is a handle).
793ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
794ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // etc. Saves context (esi). If space was reserved for return value then
795ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  // stores the pointer to the reserved slot into esi.
796662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void PrepareCallApiFunction(int argc);
797c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
798c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Calls an API function.  Allocates HandleScope, extracts returned value
799c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // from handle and propagates exceptions.  Clobbers ebx, edi and
800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // caller-save registers.  Restores context.  On return removes
801c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // stack_space * kPointerSize (GCed).
802e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org  void CallApiFunctionAndReturn(Register function_address,
803a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org                                ExternalReference thunk_ref,
804b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Operand thunk_last_arg,
805bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                int stack_space,
806528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                Operand return_value_operand,
807528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                Operand* context_restore_operand);
8082d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org
809c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // Jump to a runtime routine.
810ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void JumpToExternalReference(const ExternalReference& ext);
81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
812236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // ---------------------------------------------------------------------------
813236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // Utilities
814236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
81543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void Ret();
81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
817d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Return and drop arguments from stack, where the number of arguments
818d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // may be bigger than 2^16 - 1.  Requires a scratch register.
819d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  void Ret(int bytes_dropped, Register scratch);
820d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
8210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Emit code to discard a non-negative number of pointer-sized elements
8220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // from the stack, clobbering only the esp register.
82313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void Drop(int element_count);
82413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
82513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void Call(Label* target) { call(target); }
826594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Push(Register src) { push(src); }
827594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Pop(Register dst) { pop(dst); }
82813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Emit call to the code we are currently generating.
830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void CallSelf() {
831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    call(self, RelocInfo::CODE_TARGET);
833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8354a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // Move if the registers are not identical.
8364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void Move(Register target, Register source);
8374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
838a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  // Move a constant into a destination using the most efficient encoding.
839a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  void Move(Register dst, const Immediate& x);
840a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  void Move(const Operand& dst, const Immediate& x);
841486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
842fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // Move an immediate into an XMM register.
843fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  void Move(XMMRegister dst, double val);
844fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org
8456d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Push a handle value.
84664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void Push(Handle<Object> handle) { push(Immediate(handle)); }
84709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
8486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
849c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Handle<Object> CodeObject() {
850c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    ASSERT(!code_object_.is_null());
851c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return code_object_;
852c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
853061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
854763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Emit code for a truncating division by a constant. The dividend register is
855bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  // unchanged, the result is in edx, and eax gets clobbered.
856763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void TruncatingDiv(Register dividend, int32_t divisor);
857bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // StatsCounter support
86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void SetCounter(StatsCounter* counter, int value);
86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void IncrementCounter(StatsCounter* counter, int value);
86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void DecrementCounter(StatsCounter* counter, int value);
864b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void IncrementCounter(Condition cc, StatsCounter* counter, int value);
865b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void DecrementCounter(Condition cc, StatsCounter* counter, int value);
86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
86943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugging
87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Calls Abort(msg) if the condition cc is not satisfied.
87243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Use --debug_code to enable.
873594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Assert(Condition cc, BailoutReason reason);
87443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8750b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  void AssertFastElements(Register elements);
8760b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Like Assert(), but always enabled.
878594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Check(Condition cc, BailoutReason reason);
87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Print a message to stdout and abort execution.
881594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Abort(BailoutReason reason);
88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
883c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Check that the stack is aligned.
884c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  void CheckStackAlignment();
885c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Verify restrictions about code generated in stubs.
88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void set_generating_stub(bool value) { generating_stub_ = value; }
88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool generating_stub() { return generating_stub_; }
889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void set_has_frame(bool value) { has_frame_ = value; }
890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame() { return has_frame_; }
891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline bool AllowThisStubCall(CodeStub* stub);
89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
893b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // ---------------------------------------------------------------------------
894b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // String utilities.
895b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
896528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Generate code to do a lookup in the number string cache. If the number in
897528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // the register object is found in the cache the generated code falls through
898528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // with the result in the result register. The object and the result register
899528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // can be the same. If the number is not found in the cache the code jumps to
900528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // the label not_found with only the content of register object unchanged.
901528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LookupNumberStringCache(Register object,
902528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register result,
903528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch1,
904528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch2,
905528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Label* not_found);
906528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
9072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Check whether the instance type represents a flat ASCII string. Jump to the
9085c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // label if not. If the instance type can be scratched specify same register
9095c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // for both instance type and scratch.
9105c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type,
9115c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                              Register scratch,
912cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org                                              Label* on_not_flat_ascii_string);
9135c838251403b0be9a882540f1922577abba4c872ager@chromium.org
914b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Checks if both objects are sequential ASCII strings, and jumps to label
915b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // if either is not.
916b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void JumpIfNotBothSequentialAsciiStrings(Register object1,
917b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                           Register object2,
918b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                           Register scratch1,
919b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                                           Register scratch2,
920cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org                                           Label* on_not_flat_ascii_strings);
921b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
9221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Checks if the given register or operand is a unique name
9231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void JumpIfNotUniqueName(Register reg, Label* not_unique_name,
9241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                           Label::Distance distance = Label::kFar) {
9251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    JumpIfNotUniqueName(Operand(reg), not_unique_name, distance);
9261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
9271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
9281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void JumpIfNotUniqueName(Operand operand, Label* not_unique_name,
9291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                           Label::Distance distance = Label::kFar);
9301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
9319af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  void EmitSeqStringSetCharCheck(Register string,
9329af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 Register index,
9339af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 Register value,
9349af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 uint32_t encoding_mask);
9359af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
93644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  static int SafepointRegisterStackIndex(Register reg) {
93744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    return SafepointRegisterStackIndex(reg.code());
93844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
93944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Activation support.
941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EnterFrame(StackFrame::Type type);
942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void LeaveFrame(StackFrame::Type type);
943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
944be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Expects object in eax and returns map with validated enum cache
945be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // in eax.  Assumes that any other register can be used as a scratch.
946be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void CheckEnumCache(Label* call_runtime);
947be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
948ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento support. Arrays may have an associated
949ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento object that can be checked for in order to pretransition
95059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // to another type.
95159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // On entry, receiver_reg should point to the array object.
95259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // scratch_reg gets clobbered.
953b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // If allocation info is present, conditional code is set to equal.
954ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  void TestJSArrayForAllocationMemento(Register receiver_reg,
955b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                       Register scratch_reg,
956b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                       Label* no_memento_found);
957b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
958b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
959b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                         Register scratch_reg,
960b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                         Label* memento_found) {
961b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Label no_memento_found;
962b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
963b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                    &no_memento_found);
964b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    j(equal, memento_found);
965b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bind(&no_memento_found);
966b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  }
96759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
968e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Jumps to found label if a prototype map has dictionary elements.
969e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
970e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                        Register scratch1, Label* found);
971e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
97243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool generating_stub_;
974c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame_;
9755c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // This handle will be patched with the code object on installation.
9765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Handle<Object> code_object_;
97743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
97843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Helper functions for generating invokes.
97943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void InvokePrologue(const ParameterCount& expected,
98043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      const ParameterCount& actual,
98143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      Handle<Code> code_constant,
98243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                      const Operand& code_operand,
98383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                      Label* done,
9842efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                      bool* definitely_mismatches,
985a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                      InvokeFlag flag,
986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label::Distance done_distance,
987e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper = NullCallWrapper());
988b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
989d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void EnterExitFramePrologue();
990a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void EnterExitFrameEpilogue(int argc, bool save_doubles);
991c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
992528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LeaveExitFrameEpilogue(bool restore_context);
9934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
99418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Allocation support helpers.
99518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void LoadAllocationTopHelper(Register result,
99618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org                               Register scratch,
997a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                               AllocationFlags flags);
9982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
9992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  void UpdateAllocationTopHelper(Register result_end,
10002bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                 Register scratch,
10012bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                 AllocationFlags flags);
10022d5475fff35304176dd2752aac16d652ddfc600bkmillikin@chromium.org
1003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
1004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InNewSpace(Register object,
1005c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Register scratch,
1006c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Condition cc,
1007c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Label* condition_met,
1008c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Label::Distance condition_met_distance = Label::kFar);
1009c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1010c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Helper for finding the mark bits for an address.  Afterwards, the
1011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // bitmap register points at the word with the mark bits and the mask
1012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the position of the first bit.  Uses ecx as scratch and leaves addr_reg
1013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // unchanged.
1014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline void GetMarkBits(Register addr_reg,
1015c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          Register bitmap_reg,
1016c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          Register mask_reg);
10173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
101804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Helper for throwing exceptions.  Compute a handler address and jump to
101904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // it.  See the implementation for register usage.
102004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  void JumpToHandlerEntry();
102104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
10223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Compute memory operands for safepoint stack slots.
10233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  Operand SafepointRegisterSlot(Register reg);
10243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  static int SafepointRegisterStackIndex(int reg_code);
10253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1026a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Needs access to SafepointRegisterStackIndex for compiled frame
10273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // traversal.
1028a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  friend class StandardFrame;
102943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
103043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The code patcher is used to patch (typically) small parts of code e.g. for
103343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// debugging and other types of instrumentation. When using the code patcher
103443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the exact number of bytes specified must be emitted. Is not legal to emit
103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// relocation information. If any of these constraints are violated it causes
103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// an assertion.
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass CodePatcher {
103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CodePatcher(byte* address, int size);
104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  virtual ~CodePatcher();
104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Macro assembler to emit code.
104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  MacroAssembler* masm() { return &masm_; }
104443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  byte* address_;  // The address of the code being patched.
104743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int size_;  // Number of bytes of the expected patch size.
104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  MacroAssembler masm_;  // Macro assembler used to generate the code.
104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Static helper functions.
105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Generate an Operand for loading a field from an object.
10561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object, int offset) {
105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Operand(object, offset - kHeapObjectTag);
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10617276f14ca716596e0a0d17539516370c1f453847kasper.lund// Generate an Operand for loading an indexed field from an object.
10621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object,
10631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            Register index,
10641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            ScaleFactor scale,
10651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            int offset) {
10667276f14ca716596e0a0d17539516370c1f453847kasper.lund  return Operand(object, index, scale, offset - kHeapObjectTag);
10677276f14ca716596e0a0d17539516370c1f453847kasper.lund}
10687276f14ca716596e0a0d17539516370c1f453847kasper.lund
10694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
10700a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orginline Operand FixedArrayElementOperand(Register array,
10710a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                        Register index_as_smi,
10720a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org                                        int additional_offset = 0) {
10730a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
10740a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
10750a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org}
10760a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
10770a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org
10781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand ContextOperand(Register context, int index) {
10794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return Operand(context, Context::SlotOffset(index));
10804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
10814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
10824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
10831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand GlobalObjectOperand() {
108446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX);
10854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
10864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
10874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1088303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org// Generates an Operand for saving parameters after PrepareCallApiFunction.
1089662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgOperand ApiParameterOperand(int index);
1090303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
109165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
109265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef GENERATED_CODE_COVERAGE
109365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgextern void LogGeneratedCodeCoverage(const char* file_line);
109465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x
109565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
109665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
109765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define ACCESS_MASM(masm) {                                               \
109865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    byte* ia32_coverage_function =                                        \
109965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org        reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
110065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->pushfd();                                                       \
110165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->pushad();                                                       \
110265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));         \
110365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY);         \
110465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->pop(eax);                                                       \
110565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->popad();                                                        \
110665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org    masm->popfd();                                                        \
110765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  }                                                                       \
110865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  masm->
110965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#else
111065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define ACCESS_MASM(masm) masm->
111165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif
111265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
111365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_IA32_MACRO_ASSEMBLER_IA32_H_
1117