V8 Project
code-stubs-ia32.h
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_IA32_CODE_STUBS_IA32_H_
6 #define V8_IA32_CODE_STUBS_IA32_H_
7 
8 namespace v8 {
9 namespace internal {
10 
11 
13  bool construct_call,
14  Label* call_generic_code);
15 
16 
17 class StringHelper : public AllStatic {
18  public:
19  // Generate code for copying characters using the rep movs instruction.
20  // Copies ecx characters from esi to edi. Copying of overlapping regions is
21  // not supported.
23  Register dest,
24  Register src,
25  Register count,
26  Register scratch,
27  String::Encoding encoding);
28 
29  // Compares two flat one byte strings and returns result in eax.
31  Register left, Register right,
32  Register scratch1,
33  Register scratch2,
34  Register scratch3);
35 
36  // Compares two flat one byte strings for equality and returns result in eax.
38  Register left, Register right,
39  Register scratch1,
40  Register scratch2);
41 
42  private:
44  MacroAssembler* masm, Register left, Register right, Register length,
45  Register scratch, Label* chars_not_equal,
46  Label::Distance chars_not_equal_near = Label::kFar);
47 
49 };
50 
51 
53  public:
55 
58  : PlatformCodeStub(isolate) {
59  minor_key_ = DictionaryBits::encode(dictionary.code()) |
62  }
63 
65  Label* miss,
66  Label* done,
67  Register properties,
69  Register r0);
70 
72  Label* miss,
73  Label* done,
74  Register elements,
75  Register name,
76  Register r0,
77  Register r1);
78 
79  virtual bool SometimesSetsUpAFrame() { return false; }
80 
81  private:
82  static const int kInlinedProbes = 4;
83  static const int kTotalProbes = 20;
84 
85  static const int kCapacityOffset =
88 
89  static const int kElementsStartOffset =
92 
93  Register dictionary() const {
94  return Register::from_code(DictionaryBits::decode(minor_key_));
95  }
96 
97  Register result() const {
98  return Register::from_code(ResultBits::decode(minor_key_));
99  }
100 
101  Register index() const {
102  return Register::from_code(IndexBits::decode(minor_key_));
103  }
104 
105  LookupMode mode() const { return LookupModeBits::decode(minor_key_); }
106 
107  class DictionaryBits: public BitField<int, 0, 3> {};
108  class ResultBits: public BitField<int, 3, 3> {};
109  class IndexBits: public BitField<int, 6, 3> {};
110  class LookupModeBits: public BitField<LookupMode, 9, 1> {};
111 
114 };
115 
116 
117 class RecordWriteStub: public PlatformCodeStub {
118  public:
120  Register object,
121  Register value,
124  SaveFPRegsMode fp_mode)
125  : PlatformCodeStub(isolate),
126  regs_(object, // An input reg.
127  address, // An input reg.
128  value) { // One scratch reg.
129  minor_key_ = ObjectBits::encode(object.code()) |
134  }
135 
137  : PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {}
138 
139  enum Mode {
141  INCREMENTAL,
143  };
144 
145  virtual bool SometimesSetsUpAFrame() { return false; }
146 
147  static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8.
148  static const byte kTwoByteJumpInstruction = 0xeb; // Jmp #imm8.
149 
150  static const byte kFiveByteNopInstruction = 0x3d; // Cmpl eax, #imm32.
151  static const byte kFiveByteJumpInstruction = 0xe9; // Jmp #imm32.
152 
153  static Mode GetMode(Code* stub) {
154  byte first_instruction = stub->instruction_start()[0];
155  byte second_instruction = stub->instruction_start()[2];
156 
157  if (first_instruction == kTwoByteJumpInstruction) {
158  return INCREMENTAL;
159  }
160 
161  DCHECK(first_instruction == kTwoByteNopInstruction);
162 
163  if (second_instruction == kFiveByteJumpInstruction) {
164  return INCREMENTAL_COMPACTION;
165  }
166 
167  DCHECK(second_instruction == kFiveByteNopInstruction);
168 
169  return STORE_BUFFER_ONLY;
170  }
171 
172  static void Patch(Code* stub, Mode mode) {
173  switch (mode) {
174  case STORE_BUFFER_ONLY:
175  DCHECK(GetMode(stub) == INCREMENTAL ||
179  break;
180  case INCREMENTAL:
181  DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
183  break;
185  DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
188  break;
189  }
190  DCHECK(GetMode(stub) == mode);
192  }
193 
195 
196  private:
197  // This is a helper class for freeing up 3 scratch registers, where the third
198  // is always ecx (needed for shift operations). The input is two registers
199  // that must be preserved and one scratch register provided by the caller.
200  class RegisterAllocation {
201  public:
205  : object_orig_(object),
208  object_(object),
209  address_(address),
211  DCHECK(!AreAliased(scratch0, object, address, no_reg));
213  if (scratch0.is(ecx)) {
215  }
216  if (object.is(ecx)) {
218  }
219  if (address.is(ecx)) {
221  }
223  }
224 
225  void Save(MacroAssembler* masm) {
231  // We don't have to save scratch0_orig_ because it was given to us as
232  // a scratch register. But if we had to switch to a different reg then
233  // we should save the new scratch0_.
234  if (!scratch0_.is(scratch0_orig_)) masm->push(scratch0_);
235  if (!ecx.is(scratch0_orig_) &&
236  !ecx.is(object_orig_) &&
237  !ecx.is(address_orig_)) {
238  masm->push(ecx);
239  }
240  masm->push(scratch1_);
241  if (!address_.is(address_orig_)) {
242  masm->push(address_);
243  masm->mov(address_, address_orig_);
244  }
245  if (!object_.is(object_orig_)) {
246  masm->push(object_);
247  masm->mov(object_, object_orig_);
248  }
249  }
250 
251  void Restore(MacroAssembler* masm) {
252  // These will have been preserved the entire time, so we just need to move
253  // them back. Only in one case is the orig_ reg different from the plain
254  // one, since only one of them can alias with ecx.
255  if (!object_.is(object_orig_)) {
256  masm->mov(object_orig_, object_);
257  masm->pop(object_);
258  }
259  if (!address_.is(address_orig_)) {
260  masm->mov(address_orig_, address_);
261  masm->pop(address_);
262  }
263  masm->pop(scratch1_);
264  if (!ecx.is(scratch0_orig_) &&
265  !ecx.is(object_orig_) &&
266  !ecx.is(address_orig_)) {
267  masm->pop(ecx);
268  }
269  if (!scratch0_.is(scratch0_orig_)) masm->pop(scratch0_);
270  }
271 
272  // If we have to call into C then we need to save and restore all caller-
273  // saved registers that were not already preserved. The caller saved
274  // registers are eax, ecx and edx. The three scratch registers (incl. ecx)
275  // will be restored by other means so we don't bother pushing them here.
277  if (!scratch0_.is(eax) && !scratch1_.is(eax)) masm->push(eax);
278  if (!scratch0_.is(edx) && !scratch1_.is(edx)) masm->push(edx);
279  if (mode == kSaveFPRegs) {
280  masm->sub(esp,
282  // Save all XMM registers except XMM0.
283  for (int i = XMMRegister::kMaxNumRegisters - 1; i > 0; i--) {
285  masm->movsd(Operand(esp, (i - 1) * kDoubleSize), reg);
286  }
287  }
288  }
289 
292  if (mode == kSaveFPRegs) {
293  // Restore all XMM registers except XMM0.
294  for (int i = XMMRegister::kMaxNumRegisters - 1; i > 0; i--) {
296  masm->movsd(reg, Operand(esp, (i - 1) * kDoubleSize));
297  }
298  masm->add(esp,
300  }
301  if (!scratch0_.is(edx) && !scratch1_.is(edx)) masm->pop(edx);
302  if (!scratch0_.is(eax) && !scratch1_.is(eax)) masm->pop(eax);
303  }
304 
305  inline Register object() { return object_; }
306  inline Register address() { return address_; }
307  inline Register scratch0() { return scratch0_; }
308  inline Register scratch1() { return scratch1_; }
309 
310  private:
318  // Third scratch register is always ecx.
319 
321  Register r2,
322  Register r3) {
323  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
325  if (candidate.is(ecx)) continue;
326  if (candidate.is(r1)) continue;
327  if (candidate.is(r2)) continue;
328  if (candidate.is(r3)) continue;
329  return candidate;
330  }
331  UNREACHABLE();
332  return no_reg;
333  }
334  friend class RecordWriteStub;
335  };
336 
340  };
341 
342  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
343 
344  virtual void Generate(MacroAssembler* masm) OVERRIDE;
347  MacroAssembler* masm,
349  Mode mode);
351 
352  void Activate(Code* code) {
354  }
355 
356  Register object() const {
357  return Register::from_code(ObjectBits::decode(minor_key_));
358  }
359 
360  Register value() const {
361  return Register::from_code(ValueBits::decode(minor_key_));
362  }
363 
364  Register address() const {
365  return Register::from_code(AddressBits::decode(minor_key_));
366  }
367 
369  return RememberedSetActionBits::decode(minor_key_);
370  }
371 
373  return SaveFPRegsModeBits::decode(minor_key_);
374  }
375 
376  class ObjectBits: public BitField<int, 0, 3> {};
377  class ValueBits: public BitField<int, 3, 3> {};
378  class AddressBits: public BitField<int, 6, 3> {};
379  class RememberedSetActionBits: public BitField<RememberedSetAction, 9, 1> {};
380  class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 10, 1> {};
381 
382  RegisterAllocation regs_;
383 
385 };
386 
387 
388 } } // namespace v8::internal
389 
390 #endif // V8_IA32_CODE_STUBS_IA32_H_
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void sub(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void movsd(XMMRegister dst, XMMRegister src)
static U encode(T value)
Definition: utils.h:217
static T decode(U value)
Definition: utils.h:228
byte * instruction_start()
Definition: objects-inl.h:6176
static void FlushICache(void *start, size_t size)
Source to read snapshot and builtins files from.
Definition: lithium-arm.h:372
static const int kHeaderSize
Definition: objects.h:2393
static const int kElementsStartIndex
Definition: objects.h:3274
static const int kCapacityIndex
Definition: objects.h:3272
Heap * GetHeap() const
Definition: objects-inl.h:1379
IncrementalMarking * incremental_marking()
Definition: heap.h:1205
void mov(Register rd, Register rt)
static void GeneratePositiveLookup(MacroAssembler *masm, Label *miss, Label *done, Register elements, Register name, Register r0, Register r1)
NameDictionaryLookupStub(Isolate *isolate, Register dictionary, Register result, Register index, LookupMode mode)
DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub)
static void GenerateNegativeLookup(MacroAssembler *masm, Label *miss, Label *done, Register properties, Handle< Name > name, Register r0)
void SaveCallerSaveRegisters(MacroAssembler *masm, SaveFPRegsMode mode)
RegisterAllocation(Register object, Register address, Register scratch0)
Register GetRegThatIsNotEcxOr(Register r1, Register r2, Register r3)
void RestoreCallerSaveRegisters(MacroAssembler *masm, SaveFPRegsMode mode)
void GenerateIncremental(MacroAssembler *masm, Mode mode)
void InformIncrementalMarker(MacroAssembler *masm)
RememberedSetAction remembered_set_action() const
SaveFPRegsMode save_fp_regs_mode() const
RecordWriteStub(Isolate *isolate, Register object, Register value, Register address, RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode)
static const byte kTwoByteNopInstruction
RecordWriteStub(uint32_t key, Isolate *isolate)
virtual Major MajorKey() const FINAL OVERRIDE
static const byte kFiveByteJumpInstruction
void CheckNeedsToInformIncrementalMarker(MacroAssembler *masm, OnNoNeedToInformIncrementalMarker on_no_need, Mode mode)
DISALLOW_COPY_AND_ASSIGN(RecordWriteStub)
static const byte kFiveByteNopInstruction
static void Patch(Code *stub, Mode mode)
static const byte kTwoByteJumpInstruction
static Mode GetMode(Code *stub)
virtual void Generate(MacroAssembler *masm) OVERRIDE
static void GenerateCompareFlatOneByteStrings(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3)
static void GenerateFlatOneByteStringEquals(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2)
static void GenerateOneByteCharsCompareLoop(MacroAssembler *masm, Register left, Register right, Register length, Register scratch, Label *chars_not_equal, Label::Distance chars_not_equal_near=Label::kFar)
DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper)
static void GenerateCopyCharacters(MacroAssembler *masm, Register dest, Register src, Register count, Register scratch, String::Encoding encoding)
#define OVERRIDE
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
#define UNREACHABLE()
Definition: logging.h:30
#define DCHECK(condition)
Definition: logging.h:205
const int kPointerSize
Definition: globals.h:129
const Register edx
const Register r2
bool AreAliased(const CPURegister &reg1, const CPURegister &reg2, const CPURegister &reg3=NoReg, const CPURegister &reg4=NoReg, const CPURegister &reg5=NoReg, const CPURegister &reg6=NoReg, const CPURegister &reg7=NoReg, const CPURegister &reg8=NoReg)
const Register esp
const Register r0
const int kDoubleSize
Definition: globals.h:127
const Register r3
void ArrayNativeCode(MacroAssembler *masm, Label *call_generic_code)
const Register eax
const Register r1
const Register no_reg
const Register ecx
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
static Register from_code(int code)
static Register FromAllocationIndex(int index)
bool is(Register reg) const
static int NumAllocatableRegisters()
static const int kMaxNumRegisters
static XMMRegister from_code(int code)