V8 Project
code-stubs.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/v8.h"
6 
7 #include "src/bootstrapper.h"
8 #include "src/code-stubs.h"
9 #include "src/cpu-profiler.h"
10 #include "src/factory.h"
11 #include "src/gdb-jit.h"
13 #include "src/ic/ic.h"
14 #include "src/macro-assembler.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 
21  : call_descriptor_(stub->GetCallInterfaceDescriptor()),
22  stack_parameter_count_(no_reg),
23  hint_stack_parameter_count_(-1),
24  function_mode_(NOT_JS_FUNCTION_STUB_MODE),
25  deoptimization_handler_(NULL),
26  handler_arguments_mode_(DONT_PASS_ARGUMENTS),
27  miss_handler_(),
28  has_miss_handler_(false) {
29  stub->InitializeDescriptor(this);
30 }
31 
32 
34  : stack_parameter_count_(no_reg),
35  hint_stack_parameter_count_(-1),
36  function_mode_(NOT_JS_FUNCTION_STUB_MODE),
37  deoptimization_handler_(NULL),
38  handler_arguments_mode_(DONT_PASS_ARGUMENTS),
39  miss_handler_(),
40  has_miss_handler_(false) {
41  CodeStub::InitializeDescriptor(isolate, stub_key, this);
42 }
43 
44 
45 void CodeStubDescriptor::Initialize(Address deoptimization_handler,
46  int hint_stack_parameter_count,
47  StubFunctionMode function_mode) {
51 }
52 
53 
54 void CodeStubDescriptor::Initialize(Register stack_parameter_count,
55  Address deoptimization_handler,
56  int hint_stack_parameter_count,
57  StubFunctionMode function_mode,
58  HandlerArgumentsMode handler_mode) {
61  handler_arguments_mode_ = handler_mode;
62 }
63 
64 
65 bool CodeStub::FindCodeInCache(Code** code_out) {
66  UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
67  int index = stubs->FindEntry(GetKey());
69  *code_out = Code::cast(stubs->ValueAt(index));
70  return true;
71  }
72  return false;
73 }
74 
75 
76 void CodeStub::RecordCodeGeneration(Handle<Code> code) {
78  OStringStream os;
79  os << *this;
80  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, os.c_str()));
81  Counters* counters = isolate()->counters();
82  counters->total_stubs_code_size()->Increment(code->instruction_size());
83 }
84 
85 
86 Code::Kind CodeStub::GetCodeKind() const {
87  return Code::STUB;
88 }
89 
90 
91 Handle<Code> CodeStub::GetCodeCopy(const Code::FindAndReplacePattern& pattern) {
92  Handle<Code> ic = GetCode();
93  ic = isolate()->factory()->CopyCode(ic);
94  ic->FindAndReplace(pattern);
95  RecordCodeGeneration(ic);
96  return ic;
97 }
98 
99 
101  Factory* factory = isolate()->factory();
102 
103  // Generate the new code.
104  MacroAssembler masm(isolate(), NULL, 256);
105 
106  // TODO(yangguo) remove this once the code serializer handles code stubs.
107  if (FLAG_serialize_toplevel) masm.enable_serializer();
108 
109  {
110  // Update the static counter each time a new code stub is generated.
111  isolate()->counters()->code_stubs()->Increment();
112 
113  // Generate the code for the stub.
114  masm.set_generating_stub(true);
115  NoCurrentFrameScope scope(&masm);
116  Generate(&masm);
117  }
118 
119  // Create the code object.
120  CodeDesc desc;
121  masm.GetCode(&desc);
122 
123  // Copy the generated code into a heap object.
125  GetCodeKind(),
126  GetICState(),
127  GetExtraICState(),
128  GetStubType());
129  Handle<Code> new_object = factory->NewCode(
130  desc, flags, masm.CodeObject(), NeedsImmovableCode());
131  return new_object;
132 }
133 
134 
135 Handle<Code> CodeStub::GetCode() {
136  Heap* heap = isolate()->heap();
137  Code* code;
138  if (UseSpecialCache() ? FindCodeInSpecialCache(&code)
139  : FindCodeInCache(&code)) {
140  DCHECK(GetCodeKind() == code->kind());
141  return Handle<Code>(code);
142  }
143 
144  {
145  HandleScope scope(isolate());
146 
147  Handle<Code> new_object = GenerateCode();
148  new_object->set_stub_key(GetKey());
149  FinishCode(new_object);
150  RecordCodeGeneration(new_object);
151 
152 #ifdef ENABLE_DISASSEMBLER
153  if (FLAG_print_code_stubs) {
154  CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
155  OFStream os(trace_scope.file());
156  OStringStream name;
157  name << *this;
158  new_object->Disassemble(name.c_str(), os);
159  os << "\n";
160  }
161 #endif
162 
163  if (UseSpecialCache()) {
164  AddToSpecialCache(new_object);
165  } else {
166  // Update the dictionary and the root in Heap.
167  Handle<UnseededNumberDictionary> dict =
169  Handle<UnseededNumberDictionary>(heap->code_stubs()),
170  GetKey(),
171  new_object);
172  heap->public_set_code_stubs(*dict);
173  }
174  code = *new_object;
175  }
176 
177  Activate(code);
178  DCHECK(!NeedsImmovableCode() ||
179  heap->lo_space()->Contains(code) ||
180  heap->code_space()->FirstPage()->Contains(code->address()));
181  return Handle<Code>(code, isolate());
182 }
183 
184 
185 const char* CodeStub::MajorName(CodeStub::Major major_key,
186  bool allow_unknown_keys) {
187  switch (major_key) {
188 #define DEF_CASE(name) case name: return #name "Stub";
190 #undef DEF_CASE
191  case NoCache:
192  return "<NoCache>Stub";
193  case NUMBER_OF_IDS:
194  UNREACHABLE();
195  return NULL;
196  }
197  return NULL;
198 }
199 
200 
201 void CodeStub::PrintBaseName(OStream& os) const { // NOLINT
202  os << MajorName(MajorKey(), false);
203 }
204 
205 
206 void CodeStub::PrintName(OStream& os) const { // NOLINT
207  PrintBaseName(os);
208  PrintState(os);
209 }
210 
211 
212 void CodeStub::Dispatch(Isolate* isolate, uint32_t key, void** value_out,
213  DispatchedCall call) {
214  switch (MajorKeyFromKey(key)) {
215 #define DEF_CASE(NAME) \
216  case NAME: { \
217  NAME##Stub stub(key, isolate); \
218  CodeStub* pstub = &stub; \
219  call(pstub, value_out); \
220  break; \
221  }
223 #undef DEF_CASE
224  case NUMBER_OF_IDS:
225  UNREACHABLE();
226  case NoCache:
227  *value_out = NULL;
228  break;
229  }
230 }
231 
232 
234  void** value_out) {
235  CodeStubDescriptor* descriptor_out =
236  reinterpret_cast<CodeStubDescriptor*>(value_out);
237  stub->InitializeDescriptor(descriptor_out);
238  descriptor_out->set_call_descriptor(stub->GetCallInterfaceDescriptor());
239 }
240 
241 
242 void CodeStub::InitializeDescriptor(Isolate* isolate, uint32_t key,
243  CodeStubDescriptor* desc) {
244  void** value_out = reinterpret_cast<void**>(desc);
245  Dispatch(isolate, key, value_out, &InitializeDescriptorDispatchedCall);
246 }
247 
248 
249 void CodeStub::GetCodeDispatchCall(CodeStub* stub, void** value_out) {
250  Handle<Code>* code_out = reinterpret_cast<Handle<Code>*>(value_out);
251  // Code stubs with special cache cannot be recreated from stub key.
252  *code_out = stub->UseSpecialCache() ? Handle<Code>() : stub->GetCode();
253 }
254 
255 
256 MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
257  HandleScope scope(isolate);
258  Handle<Code> code;
259  void** value_out = reinterpret_cast<void**>(&code);
260  Dispatch(isolate, key, value_out, &GetCodeDispatchCall);
261  return scope.CloseAndEscape(code);
262 }
263 
264 
265 // static
267  // Generate the uninitialized versions of the stub.
268  for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
269  for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
270  BinaryOpICStub stub(isolate,
271  static_cast<Token::Value>(op),
272  static_cast<OverwriteMode>(mode));
273  stub.GetCode();
274  }
275  }
276 
277  // Generate special versions of the stub.
278  BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
279 }
280 
281 
282 void BinaryOpICStub::PrintState(OStream& os) const { // NOLINT
283  os << state();
284 }
285 
286 
287 // static
289  const BinaryOpICState& state) {
290  BinaryOpICStub stub(isolate, state);
291  stub.GetCode();
292 }
293 
294 
295 // static
296 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
297  // Generate special versions of the stub.
298  BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
299 }
300 
301 
302 void BinaryOpICWithAllocationSiteStub::PrintState(
303  OStream& os) const { // NOLINT
304  os << state();
305 }
306 
307 
308 // static
309 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
310  Isolate* isolate, const BinaryOpICState& state) {
311  if (state.CouldCreateAllocationMementos()) {
312  BinaryOpICWithAllocationSiteStub stub(isolate, state);
313  stub.GetCode();
314  }
315 }
316 
317 
318 void StringAddStub::PrintBaseName(OStream& os) const { // NOLINT
319  os << "StringAddStub";
321  os << "_CheckBoth";
322  } else if ((flags() & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
323  os << "_CheckLeft";
325  os << "_CheckRight";
326  }
327  if (pretenure_flag() == TENURED) {
328  os << "_Tenured";
329  }
330 }
331 
332 
335  switch (state) {
338  case CompareICState::SMI:
345  return MONOMORPHIC;
348  }
349  UNREACHABLE();
351 }
352 
353 
356 }
357 
358 
360  DCHECK(*known_map_ != NULL);
361  Isolate* isolate = new_object->GetIsolate();
362  Factory* factory = isolate->factory();
364  strict() ?
365  factory->strict_compare_ic_string() :
366  factory->compare_ic_string(),
367  new_object);
368 }
369 
370 
372  Factory* factory = isolate()->factory();
374  GetCodeKind(),
375  UNINITIALIZED);
376  DCHECK(op() == Token::EQ || op() == Token::EQ_STRICT);
377  Handle<Object> probe(
378  known_map_->FindInCodeCache(
379  strict() ?
380  *factory->strict_compare_ic_string() :
381  *factory->compare_ic_string(),
382  flags),
383  isolate());
384  if (probe->IsCode()) {
385  *code_out = Code::cast(*probe);
386 #ifdef DEBUG
387  CompareICStub decode((*code_out)->stub_key(), isolate());
388  DCHECK(op() == decode.op());
389  DCHECK(left() == decode.left());
390  DCHECK(right() == decode.right());
391  DCHECK(state() == decode.state());
392 #endif
393  return true;
394  }
395  return false;
396 }
397 
398 
400  switch (state()) {
402  GenerateMiss(masm);
403  break;
404  case CompareICState::SMI:
405  GenerateSmis(masm);
406  break;
408  GenerateNumbers(masm);
409  break;
411  GenerateStrings(masm);
412  break;
415  break;
417  GenerateUniqueNames(masm);
418  break;
420  GenerateObjects(masm);
421  break;
423  DCHECK(*known_map_ != NULL);
424  GenerateKnownObjects(masm);
425  break;
427  GenerateGeneric(masm);
428  break;
429  }
430 }
431 
432 
434  State state = this->state();
435  DCHECK(!state.Contains(GENERIC));
436  State old_state = state;
437  if (object->IsNull()) {
439  } else if (object->IsUndefined()) {
441  } else if (object->IsUndetectableObject() ||
442  object->IsOddball() ||
443  !object->IsHeapObject()) {
444  state.RemoveAll();
445  state.Add(GENERIC);
446  } else if (IsMonomorphic()) {
447  state.RemoveAll();
448  state.Add(GENERIC);
449  } else {
451  }
452  TraceTransition(old_state, state);
454 }
455 
456 
457 template<class StateType>
458 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
459  // Note: Although a no-op transition is semantically OK, it is hinting at a
460  // bug somewhere in our state transition machinery.
461  DCHECK(from != to);
462  if (!FLAG_trace_ic) return;
463  OFStream os(stdout);
464  os << "[";
465  PrintBaseName(os);
466  os << ": " << from << "=>" << to << "]" << endl;
467 }
468 
469 
470 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT
471  CodeStub::PrintBaseName(os);
472  os << ((nil_value() == kNullValue) ? "(NullValue)" : "(UndefinedValue)");
473 }
474 
475 
476 void CompareNilICStub::PrintState(OStream& os) const { // NOLINT
477  os << state();
478 }
479 
480 
481 // TODO(svenpanne) Make this a real infix_ostream_iterator.
483  public:
484  explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {}
485 
486  void Add(const char* s) {
487  if (first_) {
488  first_ = false;
489  } else {
490  os_ << ",";
491  }
492  os_ << s;
493  }
494 
495  private:
497  bool first_;
498 };
499 
500 
502  os << "(";
503  SimpleListPrinter p(os);
504  if (s.IsEmpty()) p.Add("None");
505  if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined");
506  if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null");
507  if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap");
508  if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic");
509  return os << ")";
510 }
511 
512 
514  State state = this->state();
515  if (state.Contains(CompareNilICStub::GENERIC)) return Type::Any(zone);
516 
517  Type* result = Type::None(zone);
519  result = Type::Union(result, Type::Undefined(zone), zone);
520  }
522  result = Type::Union(result, Type::Null(zone), zone);
523  }
525  Type* type =
526  map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone);
527  result = Type::Union(result, type, zone);
528  }
529 
530  return result;
531 }
532 
533 
535  Type* output_type = GetType(zone, map);
536  Type* nil_type =
537  nil_value() == kNullValue ? Type::Null(zone) : Type::Undefined(zone);
538  return Type::Union(output_type, nil_type, zone);
539 }
540 
541 
542 void CallIC_ArrayStub::PrintState(OStream& os) const { // NOLINT
543  os << state() << " (Array)";
544 }
545 
546 
547 void CallICStub::PrintState(OStream& os) const { // NOLINT
548  os << state();
549 }
550 
551 
552 void InstanceofStub::PrintName(OStream& os) const { // NOLINT
553  os << "InstanceofStub";
554  if (HasArgsInRegisters()) os << "_REGS";
555  if (HasCallSiteInlineCheck()) os << "_INLINE";
556  if (ReturnTrueFalseObject()) os << "_TRUEFALSE";
557 }
558 
559 
561  Handle<FixedArray> handler_table =
562  code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
563  handler_table->set(0, Smi::FromInt(handler_offset_));
564  code->set_handler_table(*handler_table);
565 }
566 
567 
568 void LoadFastElementStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
569  descriptor->Initialize(FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
570 }
571 
572 
573 void LoadDictionaryElementStub::InitializeDescriptor(
574  CodeStubDescriptor* descriptor) {
575  descriptor->Initialize(FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
576 }
577 
578 
579 void KeyedLoadGenericStub::InitializeDescriptor(
580  CodeStubDescriptor* descriptor) {
581  descriptor->Initialize(
582  Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry);
583 }
584 
585 
587  if (kind() == Code::STORE_IC) {
588  descriptor->Initialize(FUNCTION_ADDR(StoreIC_MissFromStubFailure));
589  } else if (kind() == Code::KEYED_LOAD_IC) {
590  descriptor->Initialize(FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
591  }
592 }
593 
594 
596  if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
597  return LoadDescriptor(isolate());
598  } else {
599  DCHECK_EQ(Code::STORE_IC, kind());
600  return StoreDescriptor(isolate());
601  }
602 }
603 
604 
605 void StoreFastElementStub::InitializeDescriptor(
606  CodeStubDescriptor* descriptor) {
607  descriptor->Initialize(FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
608 }
609 
610 
611 void ElementsTransitionAndStoreStub::InitializeDescriptor(
612  CodeStubDescriptor* descriptor) {
613  descriptor->Initialize(FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
614 }
615 
616 
617 static void InitializeVectorLoadStub(Isolate* isolate,
618  CodeStubDescriptor* descriptor,
619  Address deoptimization_handler) {
620  DCHECK(FLAG_vector_ics);
621  descriptor->Initialize(deoptimization_handler);
622 }
623 
624 
625 void VectorLoadStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
626  InitializeVectorLoadStub(isolate(), descriptor,
627  FUNCTION_ADDR(VectorLoadIC_MissFromStubFailure));
628 }
629 
630 
631 void VectorKeyedLoadStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
633  isolate(), descriptor,
634  FUNCTION_ADDR(VectorKeyedLoadIC_MissFromStubFailure));
635 }
636 
637 
638 void MegamorphicLoadStub::InitializeDescriptor(CodeStubDescriptor* d) {}
639 
640 
641 void FastNewClosureStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
642  descriptor->Initialize(
643  Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry);
644 }
645 
646 
647 void FastNewContextStub::InitializeDescriptor(CodeStubDescriptor* d) {}
648 
649 
650 void ToNumberStub::InitializeDescriptor(CodeStubDescriptor* d) {}
651 
652 
653 void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
654  NumberToStringDescriptor call_descriptor(isolate());
655  descriptor->Initialize(
656  Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry);
657 }
658 
659 
660 void FastCloneShallowArrayStub::InitializeDescriptor(
661  CodeStubDescriptor* descriptor) {
662  FastCloneShallowArrayDescriptor call_descriptor(isolate());
663  descriptor->Initialize(
664  Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry);
665 }
666 
667 
668 void FastCloneShallowObjectStub::InitializeDescriptor(
669  CodeStubDescriptor* descriptor) {
670  FastCloneShallowObjectDescriptor call_descriptor(isolate());
671  descriptor->Initialize(
672  Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry);
673 }
674 
675 
676 void CreateAllocationSiteStub::InitializeDescriptor(CodeStubDescriptor* d) {}
677 
678 
679 void RegExpConstructResultStub::InitializeDescriptor(
680  CodeStubDescriptor* descriptor) {
681  descriptor->Initialize(
682  Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry);
683 }
684 
685 
686 void TransitionElementsKindStub::InitializeDescriptor(
687  CodeStubDescriptor* descriptor) {
688  descriptor->Initialize(
689  Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry);
690 }
691 
692 
693 void CompareNilICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
694  descriptor->Initialize(FUNCTION_ADDR(CompareNilIC_Miss));
695  descriptor->SetMissHandler(
696  ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
697 }
698 
699 
700 void ToBooleanStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
701  descriptor->Initialize(FUNCTION_ADDR(ToBooleanIC_Miss));
702  descriptor->SetMissHandler(
703  ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
704 }
705 
706 
707 void BinaryOpICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
708  descriptor->Initialize(FUNCTION_ADDR(BinaryOpIC_Miss));
709  descriptor->SetMissHandler(
710  ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
711 }
712 
713 
714 void BinaryOpWithAllocationSiteStub::InitializeDescriptor(
715  CodeStubDescriptor* descriptor) {
716  descriptor->Initialize(FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
717 }
718 
719 
720 void StringAddStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
721  descriptor->Initialize(Runtime::FunctionForId(Runtime::kStringAdd)->entry);
722 }
723 
724 
726  CreateAllocationSiteStub stub(isolate);
727  stub.GetCode();
728 }
729 
730 
732  switch (elements_kind()) {
733  case FAST_ELEMENTS:
734  case FAST_HOLEY_ELEMENTS:
735  case FAST_SMI_ELEMENTS:
739 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
740  case EXTERNAL_##TYPE##_ELEMENTS: \
741  case TYPE##_ELEMENTS:
742 
744 #undef TYPED_ARRAY_CASE
745  UNREACHABLE();
746  break;
747  case DICTIONARY_ELEMENTS:
749  break;
751  UNREACHABLE();
752  break;
753  }
754 }
755 
756 
757 void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
758  switch (type()) {
759  case READ_ELEMENT:
760  GenerateReadElement(masm);
761  break;
762  case NEW_SLOPPY_FAST:
763  GenerateNewSloppyFast(masm);
764  break;
765  case NEW_SLOPPY_SLOW:
766  GenerateNewSloppySlow(masm);
767  break;
768  case NEW_STRICT:
769  GenerateNewStrict(masm);
770  break;
771  }
772 }
773 
774 
775 void ArgumentsAccessStub::PrintName(OStream& os) const { // NOLINT
776  os << "ArgumentsAccessStub_";
777  switch (type()) {
778  case READ_ELEMENT:
779  os << "ReadElement";
780  break;
781  case NEW_SLOPPY_FAST:
782  os << "NewSloppyFast";
783  break;
784  case NEW_SLOPPY_SLOW:
785  os << "NewSloppySlow";
786  break;
787  case NEW_STRICT:
788  os << "NewStrict";
789  break;
790  }
791  return;
792 }
793 
794 
795 void CallFunctionStub::PrintName(OStream& os) const { // NOLINT
796  os << "CallFunctionStub_Args" << argc();
797 }
798 
799 
800 void CallConstructStub::PrintName(OStream& os) const { // NOLINT
801  os << "CallConstructStub";
802  if (RecordCallTarget()) os << "_Recording";
803 }
804 
805 
806 void ArrayConstructorStub::PrintName(OStream& os) const { // NOLINT
807  os << "ArrayConstructorStub";
808  switch (argument_count()) {
809  case ANY:
810  os << "_Any";
811  break;
812  case NONE:
813  os << "_None";
814  break;
815  case ONE:
816  os << "_One";
817  break;
818  case MORE_THAN_ONE:
819  os << "_More_Than_One";
820  break;
821  }
822  return;
823 }
824 
825 
827  const char* name) const {
828  os << name << "_" << ElementsKindToString(elements_kind());
830  os << "_DISABLE_ALLOCATION_SITES";
831  }
832  return os;
833 }
834 
835 
837  Types new_types = types();
838  Types old_types = new_types;
839  bool to_boolean_value = new_types.UpdateStatus(object);
840  TraceTransition(old_types, new_types);
842  return to_boolean_value;
843 }
844 
845 
846 void ToBooleanStub::PrintState(OStream& os) const { // NOLINT
847  os << types();
848 }
849 
850 
852  os << "(";
853  SimpleListPrinter p(os);
854  if (s.IsEmpty()) p.Add("None");
855  if (s.Contains(ToBooleanStub::UNDEFINED)) p.Add("Undefined");
856  if (s.Contains(ToBooleanStub::BOOLEAN)) p.Add("Bool");
857  if (s.Contains(ToBooleanStub::NULL_TYPE)) p.Add("Null");
858  if (s.Contains(ToBooleanStub::SMI)) p.Add("Smi");
859  if (s.Contains(ToBooleanStub::SPEC_OBJECT)) p.Add("SpecObject");
860  if (s.Contains(ToBooleanStub::STRING)) p.Add("String");
861  if (s.Contains(ToBooleanStub::SYMBOL)) p.Add("Symbol");
862  if (s.Contains(ToBooleanStub::HEAP_NUMBER)) p.Add("HeapNumber");
863  return os << ")";
864 }
865 
866 
868  if (object->IsUndefined()) {
869  Add(UNDEFINED);
870  return false;
871  } else if (object->IsBoolean()) {
872  Add(BOOLEAN);
873  return object->IsTrue();
874  } else if (object->IsNull()) {
875  Add(NULL_TYPE);
876  return false;
877  } else if (object->IsSmi()) {
878  Add(SMI);
879  return Smi::cast(*object)->value() != 0;
880  } else if (object->IsSpecObject()) {
881  Add(SPEC_OBJECT);
882  return !object->IsUndetectableObject();
883  } else if (object->IsString()) {
884  Add(STRING);
885  return !object->IsUndetectableObject() &&
886  String::cast(*object)->length() != 0;
887  } else if (object->IsSymbol()) {
888  Add(SYMBOL);
889  return true;
890  } else if (object->IsHeapNumber()) {
891  DCHECK(!object->IsUndetectableObject());
892  Add(HEAP_NUMBER);
893  double value = HeapNumber::cast(*object)->value();
894  return value != 0 && !std::isnan(value);
895  } else {
896  // We should never see an internal object at runtime here!
897  UNREACHABLE();
898  return true;
899  }
900 }
901 
902 
904  return Contains(ToBooleanStub::SPEC_OBJECT)
905  || Contains(ToBooleanStub::STRING)
906  || Contains(ToBooleanStub::SYMBOL)
907  || Contains(ToBooleanStub::HEAP_NUMBER);
908 }
909 
910 
912  return Contains(ToBooleanStub::SPEC_OBJECT)
913  || Contains(ToBooleanStub::STRING);
914 }
915 
916 
920  stub1.GetCode();
921  stub2.GetCode();
922 }
923 
924 
926  intptr_t stack_pointer,
927  Isolate* isolate) {
928  FunctionEntryHook entry_hook = isolate->function_entry_hook();
929  DCHECK(entry_hook != NULL);
930  entry_hook(function, stack_pointer);
931 }
932 
933 
935  : PlatformCodeStub(isolate) {
936  minor_key_ = ArgumentCountBits::encode(ANY);
938 }
939 
940 
942  int argument_count)
943  : PlatformCodeStub(isolate) {
944  if (argument_count == 0) {
945  minor_key_ = ArgumentCountBits::encode(NONE);
946  } else if (argument_count == 1) {
947  minor_key_ = ArgumentCountBits::encode(ONE);
948  } else if (argument_count >= 2) {
950  } else {
951  UNREACHABLE();
952  }
954 }
955 
956 
958  Isolate* isolate) : PlatformCodeStub(isolate) {
960 }
961 
962 
963 } } // namespace v8::internal
A stack-allocated class that governs a number of local handles.
Definition: v8.h:802
An object reference managed by the v8 garbage collector.
Definition: v8.h:198
Isolate represents an isolated instance of the V8 engine.
Definition: v8.h:4356
void GenerateReadElement(MacroAssembler *masm)
void GenerateNewSloppySlow(MacroAssembler *masm)
virtual void PrintName(OStream &os) const OVERRIDE
Definition: code-stubs.cc:775
void GenerateNewStrict(MacroAssembler *masm)
void GenerateNewSloppyFast(MacroAssembler *masm)
static void GenerateStubsAheadOfTime(Isolate *isolate)
AllocationSiteOverrideMode override_mode() const
Definition: code-stubs.h:2034
OStream & BasePrintName(OStream &os, const char *name) const
Definition: code-stubs.cc:826
ArrayConstructorStub(Isolate *isolate, int argument_count)
Definition: code-stubs.cc:941
ArgumentCountKey argument_count() const
Definition: code-stubs.h:732
virtual void PrintName(OStream &os) const OVERRIDE
Definition: code-stubs.cc:806
void GetCode(CodeDesc *desc)
static void GenerateAheadOfTime(Isolate *isolate)
Definition: code-stubs.cc:266
BinaryOpICState state() const
Definition: code-stubs.h:1122
virtual void PrintState(OStream &os) const FINAL OVERRIDE
Definition: code-stubs.cc:282
static U update(U previous, T value)
Definition: utils.h:223
static U encode(T value)
Definition: utils.h:217
virtual void PrintName(OStream &os) const OVERRIDE
Definition: code-stubs.cc:800
virtual void PrintName(OStream &os) const OVERRIDE
Definition: code-stubs.cc:795
CallICState state() const
Definition: code-stubs.h:817
virtual void PrintState(OStream &os) const OVERRIDE
Definition: code-stubs.cc:547
virtual void PrintState(OStream &os) const OVERRIDE
Definition: code-stubs.cc:542
StubFunctionMode function_mode_
Definition: code-stubs.h:421
Address deoptimization_handler() const
Definition: code-stubs.h:413
void set_call_descriptor(CallInterfaceDescriptor d)
Definition: code-stubs.h:377
CodeStubDescriptor(CodeStub *stub)
Definition: code-stubs.cc:20
void Initialize(Address deoptimization_handler=NULL, int hint_stack_parameter_count=-1, StubFunctionMode function_mode=NOT_JS_FUNCTION_STUB_MODE)
Definition: code-stubs.cc:45
HandlerArgumentsMode handler_arguments_mode_
Definition: code-stubs.h:424
StubFunctionMode function_mode() const
Definition: code-stubs.h:412
Register stack_parameter_count() const
Definition: code-stubs.h:411
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, StubType type=NORMAL, CacheHolderFlag holder=kCacheOnReceiver)
Definition: objects-inl.h:4954
Condition GetCondition() const
Definition: code-stubs.cc:354
virtual InlineCacheState GetICState() const
Definition: code-stubs.cc:333
virtual Code::Kind GetCodeKind() const
Definition: code-stubs.h:1281
void GenerateInternalizedStrings(MacroAssembler *masm)
void GenerateStrings(MacroAssembler *masm)
CompareICState::State state() const
Definition: code-stubs.h:1278
Token::Value op() const
Definition: code-stubs.h:1268
void GenerateMiss(MacroAssembler *masm)
CompareICState::State left() const
Definition: code-stubs.h:1272
void GenerateGeneric(MacroAssembler *masm)
CompareICState::State right() const
Definition: code-stubs.h:1275
void GenerateObjects(MacroAssembler *masm)
virtual void AddToSpecialCache(Handle< Code > new_object)
Definition: code-stubs.cc:359
virtual bool FindCodeInSpecialCache(Code **code_out)
Definition: code-stubs.cc:371
void GenerateNumbers(MacroAssembler *masm)
void GenerateUniqueNames(MacroAssembler *masm)
void GenerateKnownObjects(MacroAssembler *masm)
void GenerateSmis(MacroAssembler *masm)
static Condition ComputeCondition(Token::Value op)
virtual void PrintState(OStream &os) const OVERRIDE
Definition: code-stubs.cc:476
void UpdateStatus(Handle< Object > object)
Definition: code-stubs.cc:433
Type * GetInputType(Zone *zone, Handle< Map > map)
Definition: code-stubs.cc:534
virtual void PrintBaseName(OStream &os) const OVERRIDE
Definition: code-stubs.cc:470
Type * GetType(Zone *zone, Handle< Map > map=Handle< Map >())
Definition: code-stubs.cc:513
static void GenerateAheadOfTime(Isolate *isolate)
Definition: code-stubs.cc:725
Object * ValueAt(int entry)
Definition: objects.h:3491
static void GenerateStoreSlow(MacroAssembler *masm)
bool Contains(E element) const
Definition: utils.h:851
T ToIntegral() const
Definition: utils.h:861
bool IsEmpty() const
Definition: utils.h:850
void Add(E element)
Definition: utils.h:855
virtual void InitializeDescriptor(CodeStubDescriptor *descriptor) OVERRIDE
Definition: code-stubs.cc:586
virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE
Definition: code-stubs.cc:595
virtual Code::Kind kind() const =0
static const int kNotFound
Definition: objects.h:3283
OldSpace * code_space()
Definition: heap.h:596
LargeObjectSpace * lo_space()
Definition: heap.h:600
void public_set_code_stubs(UnseededNumberDictionary *value)
Definition: heap.h:867
void TraceTransition(StateType from, StateType to)
Definition: code-stubs.cc:458
void set_sub_minor_key(uint32_t key)
Definition: code-stubs.h:463
uint32_t sub_minor_key() const
Definition: code-stubs.h:467
static void RegisterWeakMapDependency(Handle< Code > stub)
Definition: ic.cc:442
virtual void PrintName(OStream &os) const OVERRIDE
Definition: code-stubs.cc:552
bool HasCallSiteInlineCheck() const
Definition: code-stubs.h:700
bool HasArgsInRegisters() const
Definition: code-stubs.h:698
bool ReturnTrueFalseObject() const
Definition: code-stubs.h:704
static void GenerateStubsAheadOfTime(Isolate *isolate)
FunctionEntryHook function_entry_hook()
Definition: isolate.h:1078
Factory * factory()
Definition: isolate.h:982
virtual void FinishCode(Handle< Code > code)
Definition: code-stubs.cc:560
bool Contains(HeapObject *obj)
Definition: spaces.cc:2980
static void UpdateCodeCache(Handle< Map > map, Handle< Name > name, Handle< Code > code)
Definition: objects.cc:7030
bool Contains(Address addr)
Definition: spaces.h:348
virtual Handle< Code > GenerateCode() OVERRIDE
Definition: code-stubs.cc:100
virtual Code::Kind GetCodeKind() const
Definition: code-stubs.h:338
virtual void Generate(MacroAssembler *masm)=0
static void EntryHookTrampoline(intptr_t function, intptr_t stack_pointer, Isolate *isolate)
Definition: code-stubs.cc:925
static const Function * FunctionForId(FunctionId id)
Definition: runtime.cc:9312
static Smi * FromInt(int value)
Definition: objects-inl.h:1321
ElementsKind elements_kind() const
Definition: code-stubs.h:2188
static void GenerateAheadOfTime(Isolate *isolate)
Definition: code-stubs.cc:917
bool UpdateStatus(Handle< Object > object)
Definition: code-stubs.cc:867
virtual void PrintState(OStream &os) const OVERRIDE
Definition: code-stubs.cc:846
bool UpdateStatus(Handle< Object > object)
Definition: code-stubs.cc:836
static TypeHandle Class(i::Handle< i::Map > map, Region *region)
Definition: types.h:327
static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region *reg)
Definition: types.cc:737
static MUST_USE_RESULT Handle< UnseededNumberDictionary > AtNumberPut(Handle< UnseededNumberDictionary > dictionary, uint32_t key, Handle< Object > value)
Definition: objects.cc:15117
#define DEF_CASE(name)
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)
#define CODE_STUB_LIST(V)
Definition: code-stubs.h:129
#define PROFILE(IsolateGetter, Call)
Definition: cpu-profiler.h:181
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 true
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
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 FUNCTION_ADDR(f)
Definition: globals.h:195
#define UNREACHABLE()
Definition: logging.h:30
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
static void FinishCode(MacroAssembler *masm)
@ STRING_ADD_CHECK_LEFT
Definition: code-stubs.h:1214
@ STRING_ADD_CHECK_BOTH
Definition: code-stubs.h:1218
@ STRING_ADD_CHECK_RIGHT
Definition: code-stubs.h:1216
@ JS_FUNCTION_STUB_MODE
Definition: code-stubs.h:350
@ NOT_JS_FUNCTION_STUB_MODE
Definition: code-stubs.h:350
OStream & endl(OStream &os)
Definition: ostreams.cc:112
@ FAST_HOLEY_DOUBLE_ELEMENTS
Definition: elements-kind.h:27
@ SLOPPY_ARGUMENTS_ELEMENTS
Definition: elements-kind.h:31
@ FAST_HOLEY_SMI_ELEMENTS
Definition: elements-kind.h:17
const char * ElementsKindToString(ElementsKind kind)
@ NO_OVERWRITE
Definition: ic-state.h:58
@ OVERWRITE_RIGHT
Definition: ic-state.h:58
static void InitializeVectorLoadStub(Isolate *isolate, CodeStubDescriptor *descriptor, Address deoptimization_handler)
Definition: code-stubs.cc:617
static void InitializeDescriptorDispatchedCall(CodeStub *stub, void **value_out)
Definition: code-stubs.cc:233
OStream & operator<<(OStream &os, const BasicBlockProfiler &p)
@ DISABLE_ALLOCATION_SITES
Definition: code-stubs.h:718
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
byte * Address
Definition: globals.h:101
@ kNullValue
Definition: v8.h:97
const Register no_reg
@ DONT_PASS_ARGUMENTS
Definition: code-stubs.h:351
@ UNINITIALIZED
Definition: globals.h:446
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
@ None
Definition: v8.h:2211
void(* FunctionEntryHook)(uintptr_t function, uintptr_t return_addr_location)
FunctionEntryHook is the type of the profile entry hook called at entry to any generated function whe...
Definition: v8.h:4263
Handle< Primitive > Null(Isolate *isolate)
Definition: v8.h:6845
Handle< Primitive > Undefined(Isolate *isolate)
Definition: v8.h:6836
#define TYPED_ARRAYS(V)
Definition: objects.h:4433