V8 Project
lithium.cc
Go to the documentation of this file.
1 // Copyright 2012 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 #include "src/lithium.h"
6 
7 #include "src/v8.h"
8 
9 #include "src/scopes.h"
10 #include "src/serialize.h"
11 
12 #if V8_TARGET_ARCH_IA32
13 #include "src/ia32/lithium-ia32.h" // NOLINT
14 #include "src/ia32/lithium-codegen-ia32.h" // NOLINT
15 #elif V8_TARGET_ARCH_X64
16 #include "src/x64/lithium-x64.h" // NOLINT
17 #include "src/x64/lithium-codegen-x64.h" // NOLINT
18 #elif V8_TARGET_ARCH_ARM
19 #include "src/arm/lithium-arm.h" // NOLINT
20 #include "src/arm/lithium-codegen-arm.h" // NOLINT
21 #elif V8_TARGET_ARCH_MIPS
22 #include "src/mips/lithium-mips.h" // NOLINT
23 #include "src/mips/lithium-codegen-mips.h" // NOLINT
24 #elif V8_TARGET_ARCH_ARM64
25 #include "src/arm64/lithium-arm64.h" // NOLINT
26 #include "src/arm64/lithium-codegen-arm64.h" // NOLINT
27 #elif V8_TARGET_ARCH_MIPS64
28 #include "src/mips64/lithium-mips64.h" // NOLINT
29 #include "src/mips64/lithium-codegen-mips64.h" // NOLINT
30 #elif V8_TARGET_ARCH_X87
31 #include "src/x87/lithium-x87.h" // NOLINT
32 #include "src/x87/lithium-codegen-x87.h" // NOLINT
33 #else
34 #error "Unknown architecture."
35 #endif
36 
37 namespace v8 {
38 namespace internal {
39 
40 
41 void LOperand::PrintTo(StringStream* stream) {
42  LUnallocated* unalloc = NULL;
43  switch (kind()) {
44  case INVALID:
45  stream->Add("(0)");
46  break;
47  case UNALLOCATED:
48  unalloc = LUnallocated::cast(this);
49  stream->Add("v%d", unalloc->virtual_register());
50  if (unalloc->basic_policy() == LUnallocated::FIXED_SLOT) {
51  stream->Add("(=%dS)", unalloc->fixed_slot_index());
52  break;
53  }
54  switch (unalloc->extended_policy()) {
55  case LUnallocated::NONE:
56  break;
58  int reg_index = unalloc->fixed_register_index();
59  if (reg_index < 0 ||
61  stream->Add("(=invalid_reg#%d)", reg_index);
62  } else {
63  const char* register_name =
65  stream->Add("(=%s)", register_name);
66  }
67  break;
68  }
70  int reg_index = unalloc->fixed_register_index();
71  if (reg_index < 0 ||
73  stream->Add("(=invalid_double_reg#%d)", reg_index);
74  } else {
75  const char* double_register_name =
77  stream->Add("(=%s)", double_register_name);
78  }
79  break;
80  }
82  stream->Add("(R)");
83  break;
85  stream->Add("(D)");
86  break;
88  stream->Add("(WR)");
89  break;
91  stream->Add("(1)");
92  break;
93  case LUnallocated::ANY:
94  stream->Add("(-)");
95  break;
96  }
97  break;
98  case CONSTANT_OPERAND:
99  stream->Add("[constant:%d]", index());
100  break;
101  case STACK_SLOT:
102  stream->Add("[stack:%d]", index());
103  break;
104  case DOUBLE_STACK_SLOT:
105  stream->Add("[double_stack:%d]", index());
106  break;
107  case REGISTER: {
108  int reg_index = index();
109  if (reg_index < 0 || reg_index >= Register::kMaxNumAllocatableRegisters) {
110  stream->Add("(=invalid_reg#%d|R)", reg_index);
111  } else {
112  stream->Add("[%s|R]", Register::AllocationIndexToString(reg_index));
113  }
114  break;
115  }
116  case DOUBLE_REGISTER: {
117  int reg_index = index();
118  if (reg_index < 0 ||
120  stream->Add("(=invalid_double_reg#%d|R)", reg_index);
121  } else {
122  stream->Add("[%s|R]",
124  }
125  break;
126  }
127  }
128 }
129 
130 
131 template<LOperand::Kind kOperandKind, int kNumCachedOperands>
132 LSubKindOperand<kOperandKind, kNumCachedOperands>*
133 LSubKindOperand<kOperandKind, kNumCachedOperands>::cache = NULL;
134 
135 
136 template<LOperand::Kind kOperandKind, int kNumCachedOperands>
137 void LSubKindOperand<kOperandKind, kNumCachedOperands>::SetUpCache() {
138  if (cache) return;
139  cache = new LSubKindOperand[kNumCachedOperands];
140  for (int i = 0; i < kNumCachedOperands; i++) {
141  cache[i].ConvertTo(kOperandKind, i);
142  }
143 }
144 
145 
146 template<LOperand::Kind kOperandKind, int kNumCachedOperands>
147 void LSubKindOperand<kOperandKind, kNumCachedOperands>::TearDownCache() {
148  delete[] cache;
149  cache = NULL;
150 }
151 
152 
154 #define LITHIUM_OPERAND_SETUP(name, type, number) L##name::SetUpCache();
156 #undef LITHIUM_OPERAND_SETUP
157 }
158 
159 
161 #define LITHIUM_OPERAND_TEARDOWN(name, type, number) L##name::TearDownCache();
163 #undef LITHIUM_OPERAND_TEARDOWN
164 }
165 
166 
167 bool LParallelMove::IsRedundant() const {
168  for (int i = 0; i < move_operands_.length(); ++i) {
169  if (!move_operands_[i].IsRedundant()) return false;
170  }
171  return true;
172 }
173 
174 
175 void LParallelMove::PrintDataTo(StringStream* stream) const {
176  bool first = true;
177  for (int i = 0; i < move_operands_.length(); ++i) {
178  if (!move_operands_[i].IsEliminated()) {
179  LOperand* source = move_operands_[i].source();
180  LOperand* destination = move_operands_[i].destination();
181  if (!first) stream->Add(" ");
182  first = false;
183  if (source->Equals(destination)) {
184  destination->PrintTo(stream);
185  } else {
186  destination->PrintTo(stream);
187  stream->Add(" = ");
188  source->PrintTo(stream);
189  }
190  stream->Add(";");
191  }
192  }
193 }
194 
195 
196 void LEnvironment::PrintTo(StringStream* stream) {
197  stream->Add("[id=%d|", ast_id().ToInt());
198  if (deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
199  stream->Add("deopt_id=%d|", deoptimization_index());
200  }
201  stream->Add("parameters=%d|", parameter_count());
202  stream->Add("arguments_stack_height=%d|", arguments_stack_height());
203  for (int i = 0; i < values_.length(); ++i) {
204  if (i != 0) stream->Add(";");
205  if (values_[i] == NULL) {
206  stream->Add("[hole]");
207  } else {
208  values_[i]->PrintTo(stream);
209  }
210  }
211  stream->Add("]");
212 }
213 
214 
215 void LPointerMap::RecordPointer(LOperand* op, Zone* zone) {
216  // Do not record arguments as pointers.
217  if (op->IsStackSlot() && op->index() < 0) return;
218  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
219  pointer_operands_.Add(op, zone);
220 }
221 
222 
223 void LPointerMap::RemovePointer(LOperand* op) {
224  // Do not record arguments as pointers.
225  if (op->IsStackSlot() && op->index() < 0) return;
226  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
227  for (int i = 0; i < pointer_operands_.length(); ++i) {
228  if (pointer_operands_[i]->Equals(op)) {
229  pointer_operands_.Remove(i);
230  --i;
231  }
232  }
233 }
234 
235 
236 void LPointerMap::RecordUntagged(LOperand* op, Zone* zone) {
237  // Do not record arguments as pointers.
238  if (op->IsStackSlot() && op->index() < 0) return;
239  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
240  untagged_operands_.Add(op, zone);
241 }
242 
243 
244 void LPointerMap::PrintTo(StringStream* stream) {
245  stream->Add("{");
246  for (int i = 0; i < pointer_operands_.length(); ++i) {
247  if (i != 0) stream->Add(";");
248  pointer_operands_[i]->PrintTo(stream);
249  }
250  stream->Add("}");
251 }
252 
253 
254 int StackSlotOffset(int index) {
255  if (index >= 0) {
256  // Local or spill slot. Skip the frame pointer, function, and
257  // context in the fixed part of the frame.
258  return -(index + 1) * kPointerSize -
260  } else {
261  // Incoming parameter. Skip the return address.
262  return -(index + 1) * kPointerSize + kFPOnStackSize + kPCOnStackSize;
263  }
264 }
265 
266 
267 LChunk::LChunk(CompilationInfo* info, HGraph* graph)
268  : spill_slot_count_(0),
269  info_(info),
270  graph_(graph),
271  instructions_(32, info->zone()),
272  pointer_maps_(8, info->zone()),
273  inlined_closures_(1, info->zone()),
274  deprecation_dependencies_(MapLess(), MapAllocator(info->zone())),
275  stability_dependencies_(MapLess(), MapAllocator(info->zone())) {}
276 
277 
278 LLabel* LChunk::GetLabel(int block_id) const {
279  HBasicBlock* block = graph_->blocks()->at(block_id);
280  int first_instruction = block->first_instruction_index();
281  return LLabel::cast(instructions_[first_instruction]);
282 }
283 
284 
285 int LChunk::LookupDestination(int block_id) const {
286  LLabel* cur = GetLabel(block_id);
287  while (cur->replacement() != NULL) {
288  cur = cur->replacement();
289  }
290  return cur->block_id();
291 }
292 
293 Label* LChunk::GetAssemblyLabel(int block_id) const {
294  LLabel* label = GetLabel(block_id);
295  DCHECK(!label->HasReplacement());
296  return label->label();
297 }
298 
299 
301  LPhase phase("L_Mark empty blocks", this);
302  for (int i = 0; i < graph()->blocks()->length(); ++i) {
303  HBasicBlock* block = graph()->blocks()->at(i);
304  int first = block->first_instruction_index();
305  int last = block->last_instruction_index();
306  LInstruction* first_instr = instructions()->at(first);
307  LInstruction* last_instr = instructions()->at(last);
308 
309  LLabel* label = LLabel::cast(first_instr);
310  if (last_instr->IsGoto()) {
311  LGoto* goto_instr = LGoto::cast(last_instr);
312  if (label->IsRedundant() &&
313  !label->is_loop_header()) {
314  bool can_eliminate = true;
315  for (int i = first + 1; i < last && can_eliminate; ++i) {
316  LInstruction* cur = instructions()->at(i);
317  if (cur->IsGap()) {
318  LGap* gap = LGap::cast(cur);
319  if (!gap->IsRedundant()) {
320  can_eliminate = false;
321  }
322  } else {
323  can_eliminate = false;
324  }
325  }
326  if (can_eliminate) {
327  label->set_replacement(GetLabel(goto_instr->block_id()));
328  }
329  }
330  }
331  }
332 }
333 
334 
335 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
336  LInstructionGap* gap = new (zone()) LInstructionGap(block);
337  gap->set_hydrogen_value(instr->hydrogen_value());
338  int index = -1;
339  if (instr->IsControl()) {
340  instructions_.Add(gap, zone());
341  index = instructions_.length();
342  instructions_.Add(instr, zone());
343  } else {
344  index = instructions_.length();
345  instructions_.Add(instr, zone());
346  instructions_.Add(gap, zone());
347  }
348  if (instr->HasPointerMap()) {
349  pointer_maps_.Add(instr->pointer_map(), zone());
350  instr->pointer_map()->set_lithium_position(index);
351  }
352 }
353 
354 
355 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
356  return LConstantOperand::Create(constant->id(), zone());
357 }
358 
359 
360 int LChunk::GetParameterStackSlot(int index) const {
361  // The receiver is at index 0, the first parameter at index 1, so we
362  // shift all parameter indexes down by the number of parameters, and
363  // make sure they end up negative so they are distinguishable from
364  // spill slots.
365  int result = index - info()->num_parameters() - 1;
366 
367  DCHECK(result < 0);
368  return result;
369 }
370 
371 
372 // A parameter relative to ebp in the arguments stub.
373 int LChunk::ParameterAt(int index) {
374  DCHECK(-1 <= index); // -1 is the receiver.
375  return (1 + info()->scope()->num_parameters() - index) *
376  kPointerSize;
377 }
378 
379 
380 LGap* LChunk::GetGapAt(int index) const {
381  return LGap::cast(instructions_[index]);
382 }
383 
384 
385 bool LChunk::IsGapAt(int index) const {
386  return instructions_[index]->IsGap();
387 }
388 
389 
390 int LChunk::NearestGapPos(int index) const {
391  while (!IsGapAt(index)) index--;
392  return index;
393 }
394 
395 
396 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
398  LGap::START, zone())->AddMove(from, to, zone());
399 }
400 
401 
402 HConstant* LChunk::LookupConstant(LConstantOperand* operand) const {
403  return HConstant::cast(graph_->LookupValue(operand->index()));
404 }
405 
406 
408  LConstantOperand* operand) const {
409  return graph_->LookupValue(operand->index())->representation();
410 }
411 
412 
414  for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
415  iend = deprecation_dependencies_.end(); it != iend; ++it) {
416  Handle<Map> map = *it;
417  DCHECK(!map->is_deprecated());
418  DCHECK(map->CanBeDeprecated());
420  }
421 
422  for (MapSet::const_iterator it = stability_dependencies_.begin(),
423  iend = stability_dependencies_.end(); it != iend; ++it) {
424  Handle<Map> map = *it;
425  DCHECK(map->is_stable());
426  DCHECK(map->CanTransition());
428  }
429 
430  info_->CommitDependencies(code);
431 }
432 
433 
434 LChunk* LChunk::NewChunk(HGraph* graph) {
435  DisallowHandleAllocation no_handles;
437  graph->DisallowAddingNewValues();
438  int values = graph->GetMaximumValueID();
439  CompilationInfo* info = graph->info();
440  if (values > LUnallocated::kMaxVirtualRegisters) {
441  info->AbortOptimization(kNotEnoughVirtualRegistersForValues);
442  return NULL;
443  }
444  LAllocator allocator(values, graph);
445  LChunkBuilder builder(info, graph, &allocator);
446  LChunk* chunk = builder.Build();
447  if (chunk == NULL) return NULL;
448 
449  if (!allocator.Allocate(chunk)) {
450  info->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
451  return NULL;
452  }
453 
455  allocator.assigned_double_registers());
456 
457  return chunk;
458 }
459 
460 
462  MacroAssembler assembler(info()->isolate(), NULL, 0);
464  CodeStartLinePosInfoRecordEvent(
465  assembler.positions_recorder()));
466  // TODO(yangguo) remove this once the code serializer handles code stubs.
467  if (info()->will_serialize()) assembler.enable_serializer();
468  LCodeGen generator(this, &assembler, info());
469 
470  MarkEmptyBlocks();
471 
472  if (generator.GenerateCode()) {
473  generator.CheckEnvironmentUsage();
474  CodeGenerator::MakeCodePrologue(info(), "optimized");
475  Code::Flags flags = info()->flags();
476  Handle<Code> code =
478  generator.FinishCode(code);
479  CommitDependencies(code);
480  code->set_is_crankshafted(true);
481  void* jit_handler_data =
482  assembler.positions_recorder()->DetachJITHandlerData();
484  CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
485 
487  DCHECK(!(info()->isolate()->serializer_enabled() &&
488  info()->GetMustNotHaveEagerFrame() &&
489  generator.NeedsEagerFrame()));
490  return code;
491  }
492  assembler.AbortedCodeGeneration();
493  return Handle<Code>::null();
494 }
495 
496 
498  allocated_double_registers_ = allocated_registers;
500  BitVector::Iterator iterator(doubles);
501  while (!iterator.Done()) {
502  if (info()->saves_caller_doubles()) {
503  if (kDoubleSize == kPointerSize * 2) {
504  spill_slot_count_ += 2;
505  } else {
507  }
508  }
509  iterator.Advance();
510  }
511 }
512 
513 
514 void LChunkBuilderBase::Abort(BailoutReason reason) {
515  info()->AbortOptimization(reason);
516  status_ = ABORTED;
517 }
518 
519 
520 void LChunkBuilderBase::Retry(BailoutReason reason) {
521  info()->RetryOptimization(reason);
522  status_ = ABORTED;
523 }
524 
525 
527  HEnvironment* hydrogen_env, int* argument_index_accumulator,
528  ZoneList<HValue*>* objects_to_materialize) {
529  if (hydrogen_env == NULL) return NULL;
530 
531  LEnvironment* outer =
532  CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator,
533  objects_to_materialize);
534  BailoutId ast_id = hydrogen_env->ast_id();
535  DCHECK(!ast_id.IsNone() ||
536  hydrogen_env->frame_type() != JS_FUNCTION);
537 
538  int omitted_count = (hydrogen_env->frame_type() == JS_FUNCTION)
539  ? 0
540  : hydrogen_env->specials_count();
541 
542  int value_count = hydrogen_env->length() - omitted_count;
543  LEnvironment* result =
544  new(zone()) LEnvironment(hydrogen_env->closure(),
545  hydrogen_env->frame_type(),
546  ast_id,
547  hydrogen_env->parameter_count(),
548  argument_count_,
549  value_count,
550  outer,
551  hydrogen_env->entry(),
552  zone());
553  int argument_index = *argument_index_accumulator;
554 
555  // Store the environment description into the environment
556  // (with holes for nested objects)
557  for (int i = 0; i < hydrogen_env->length(); ++i) {
558  if (hydrogen_env->is_special_index(i) &&
559  hydrogen_env->frame_type() != JS_FUNCTION) {
560  continue;
561  }
562  LOperand* op;
563  HValue* value = hydrogen_env->values()->at(i);
564  CHECK(!value->IsPushArguments()); // Do not deopt outgoing arguments
565  if (value->IsArgumentsObject() || value->IsCapturedObject()) {
566  op = LEnvironment::materialization_marker();
567  } else {
568  op = UseAny(value);
569  }
570  result->AddValue(op,
571  value->representation(),
572  value->CheckFlag(HInstruction::kUint32));
573  }
574 
575  // Recursively store the nested objects into the environment
576  for (int i = 0; i < hydrogen_env->length(); ++i) {
577  if (hydrogen_env->is_special_index(i)) continue;
578 
579  HValue* value = hydrogen_env->values()->at(i);
580  if (value->IsArgumentsObject() || value->IsCapturedObject()) {
581  AddObjectToMaterialize(value, objects_to_materialize, result);
582  }
583  }
584 
585  if (hydrogen_env->frame_type() == JS_FUNCTION) {
586  *argument_index_accumulator = argument_index;
587  }
588 
589  return result;
590 }
591 
592 
593 // Add an object to the supplied environment and object materialization list.
594 //
595 // Notes:
596 //
597 // We are building three lists here:
598 //
599 // 1. In the result->object_mapping_ list (added to by the
600 // LEnvironment::Add*Object methods), we store the lengths (number
601 // of fields) of the captured objects in depth-first traversal order, or
602 // in case of duplicated objects, we store the index to the duplicate object
603 // (with a tag to differentiate between captured and duplicated objects).
604 //
605 // 2. The object fields are stored in the result->values_ list
606 // (added to by the LEnvironment.AddValue method) sequentially as lists
607 // of fields with holes for nested objects (the holes will be expanded
608 // later by LCodegen::AddToTranslation according to the
609 // LEnvironment.object_mapping_ list).
610 //
611 // 3. The auxiliary objects_to_materialize array stores the hydrogen values
612 // in the same order as result->object_mapping_ list. This is used
613 // to detect duplicate values and calculate the corresponding object index.
614 void LChunkBuilderBase::AddObjectToMaterialize(HValue* value,
615  ZoneList<HValue*>* objects_to_materialize, LEnvironment* result) {
616  int object_index = objects_to_materialize->length();
617  // Store the hydrogen value into the de-duplication array
618  objects_to_materialize->Add(value, zone());
619  // Find out whether we are storing a duplicated value
620  int previously_materialized_object = -1;
621  for (int prev = 0; prev < object_index; ++prev) {
622  if (objects_to_materialize->at(prev) == value) {
623  previously_materialized_object = prev;
624  break;
625  }
626  }
627  // Store the captured object length (or duplicated object index)
628  // into the environment. For duplicated objects, we stop here.
629  int length = value->OperandCount();
630  bool is_arguments = value->IsArgumentsObject();
631  if (previously_materialized_object >= 0) {
632  result->AddDuplicateObject(previously_materialized_object);
633  return;
634  } else {
635  result->AddNewObject(is_arguments ? length - 1 : length, is_arguments);
636  }
637  // Store the captured object's fields into the environment
638  for (int i = is_arguments ? 1 : 0; i < length; ++i) {
639  LOperand* op;
640  HValue* arg_value = value->OperandAt(i);
641  if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
642  // Insert a hole for nested objects
643  op = LEnvironment::materialization_marker();
644  } else {
645  DCHECK(!arg_value->IsPushArguments());
646  // For ordinary values, tell the register allocator we need the value
647  // to be alive here
648  op = UseAny(arg_value);
649  }
650  result->AddValue(op,
651  arg_value->representation(),
652  arg_value->CheckFlag(HInstruction::kUint32));
653  }
654  // Recursively store all the nested captured objects into the environment
655  for (int i = is_arguments ? 1 : 0; i < length; ++i) {
656  HValue* arg_value = value->OperandAt(i);
657  if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) {
658  AddObjectToMaterialize(arg_value, objects_to_materialize, result);
659  }
660  }
661 }
662 
663 
665  if (ShouldProduceTraceOutput()) {
666  isolate()->GetHTracer()->TraceLithium(name(), chunk_);
667  }
668 }
669 
670 
671 } } // namespace v8::internal
virtual void AbortedCodeGeneration()
PositionsRecorder * positions_recorder()
static void PrintCode(Handle< Code > code, CompilationInfo *info)
Definition: codegen.cc:163
static void MakeCodePrologue(CompilationInfo *info, const char *kind)
Definition: codegen.cc:97
static Handle< Code > MakeCodeEpilogue(MacroAssembler *masm, Code::Flags flags, CompilationInfo *info)
Definition: codegen.cc:139
void AbortOptimization(BailoutReason reason)
Definition: compiler.h:330
Code::Flags flags() const
Definition: compiler.cc:252
void CommitDependencies(Handle< Code > code)
Definition: compiler.cc:199
static Handle< T > null()
Definition: handles.h:123
LConstantOperand * DefineConstantOperand(HConstant *constant)
Definition: lithium.cc:355
LChunk(CompilationInfo *info, HGraph *graph)
Definition: lithium.cc:267
int LookupDestination(int block_id) const
Definition: lithium.cc:285
MapSet stability_dependencies_
Definition: lithium.h:695
void set_allocated_double_registers(BitVector *allocated_registers)
Definition: lithium.cc:497
bool IsGapAt(int index) const
Definition: lithium.cc:385
void MarkEmptyBlocks()
Definition: lithium.cc:300
BitVector * allocated_double_registers()
Definition: lithium.h:672
ZoneList< LInstruction * > instructions_
Definition: lithium.h:691
HConstant * LookupConstant(LConstantOperand *operand) const
Definition: lithium.cc:402
MapSet deprecation_dependencies_
Definition: lithium.h:694
int GetParameterStackSlot(int index) const
Definition: lithium.cc:360
CompilationInfo * info() const
Definition: lithium.h:631
Handle< Code > Codegen()
Definition: lithium.cc:461
CompilationInfo * info_
Definition: lithium.h:688
HGraph *const graph_
Definition: lithium.h:689
void AddGapMove(int index, LOperand *from, LOperand *to)
Definition: lithium.cc:396
ZoneList< LPointerMap * > pointer_maps_
Definition: lithium.h:692
std::less< Handle< Map > > MapLess
Definition: lithium.h:682
HGraph * graph() const
Definition: lithium.h:632
int ParameterAt(int index)
Definition: lithium.cc:373
LLabel * GetLabel(int block_id) const
Definition: lithium.cc:278
Label * GetAssemblyLabel(int block_id) const
Definition: lithium.cc:293
static LChunk * NewChunk(HGraph *graph)
Definition: lithium.cc:434
void CommitDependencies(Handle< Code > code) const
Definition: lithium.cc:413
Representation LookupLiteralRepresentation(LConstantOperand *operand) const
Definition: lithium.cc:407
Zone * zone() const
Definition: lithium.h:667
int NearestGapPos(int index) const
Definition: lithium.cc:390
BitVector * allocated_double_registers_
Definition: lithium.h:690
const ZoneList< LInstruction * > * instructions() const
Definition: lithium.h:634
void AddInstruction(LInstruction *instruction, HBasicBlock *block)
Definition: lithium.cc:335
LGap * GetGapAt(int index) const
Definition: lithium.cc:380
Isolate * isolate() const
Definition: lithium.h:633
void FinishCode(Handle< Code > code)
static LGap * cast(LInstruction *instr)
Definition: lithium-arm.h:337
bool IsRedundant() const
Definition: lithium-arm.cc:89
LParallelMove * GetOrCreateParallelMove(InnerPosition pos, Zone *zone)
Definition: lithium-arm.h:355
HValue * hydrogen_value() const
Definition: lithium-arm.h:239
virtual bool IsControl() const
Definition: lithium-arm.h:225
LPointerMap * pointer_map() const
Definition: lithium-arm.h:235
virtual bool IsGap() const
Definition: lithium-arm.h:223
Kind kind() const
Definition: lithium.h:40
void PrintTo(StringStream *stream)
Definition: lithium.cc:41
static void TearDownCaches()
Definition: lithium.cc:160
static void SetUpCaches()
Definition: lithium.cc:153
int index() const
Definition: lithium.h:41
static LUnallocated * cast(LOperand *op)
Definition: lithium.h:138
int virtual_register() const
Definition: lithium.h:243
static const int kMaxVirtualRegisters
Definition: lithium.h:175
int fixed_slot_index() const
Definition: lithium.h:231
ExtendedPolicy extended_policy() const
Definition: lithium.h:225
BasicPolicy basic_policy() const
Definition: lithium.h:220
int fixed_register_index() const
Definition: lithium.h:237
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:17
static void AddDependentCode(Handle< Map > map, DependentCode::DependencyGroup group, Handle< Code > code)
Definition: objects.cc:11357
static const int kFixedFrameSizeFromFp
Definition: frames.h:157
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 map
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 only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
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 enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define LITHIUM_OPERAND_SETUP(name, type, number)
#define LITHIUM_OPERAND_TEARDOWN(name, type, number)
#define LITHIUM_OPERAND_LIST(V)
Definition: lithium.h:19
#define LOG_CODE_EVENT(isolate, Call)
Definition: log.h:77
#define CHECK(condition)
Definition: logging.h:36
#define DCHECK(condition)
Definition: logging.h:205
const int kPointerSize
Definition: globals.h:129
const int kPCOnStackSize
Definition: globals.h:135
const int kDoubleSize
Definition: globals.h:127
int StackSlotOffset(int index)
Definition: lithium.cc:254
const int kFPOnStackSize
Definition: globals.h:136
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
static i::Handle< i::Context > CreateEnvironment(i::Isolate *isolate, v8::ExtensionConfiguration *extensions, v8::Handle< ObjectTemplate > global_template, v8::Handle< Value > maybe_global_proxy)
Definition: api.cc:5151
static const char * AllocationIndexToString(int index)
static const int kMaxNumAllocatableRegisters
static const char * AllocationIndexToString(int index)
static const int kMaxNumAllocatableRegisters
Definition: assembler-arm.h:96