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.
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"
12 #include "src/macro-assembler.h"
13 #include "src/stub-cache.h"
19 InterfaceDescriptor::InterfaceDescriptor()
20 : register_param_count_(-1) { }
23 CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor()
24 : stack_parameter_count_(no_reg),
25 hint_stack_parameter_count_(-1),
26 function_mode_(NOT_JS_FUNCTION_STUB_MODE),
27 deoptimization_handler_(NULL),
28 handler_arguments_mode_(DONT_PASS_ARGUMENTS),
30 has_miss_handler_(false) { }
33 void InterfaceDescriptor::Initialize(
34 int register_parameter_count,
36 Representation* register_param_representations,
37 PlatformInterfaceDescriptor* platform_descriptor) {
38 platform_specific_descriptor_ = platform_descriptor;
39 register_param_count_ = register_parameter_count;
41 // An interface descriptor must have a context register.
42 DCHECK(register_parameter_count > 0 && registers[0].is(ContextRegister()));
44 // InterfaceDescriptor owns a copy of the registers array.
45 register_params_.Reset(NewArray<Register>(register_parameter_count));
46 for (int i = 0; i < register_parameter_count; i++) {
47 register_params_[i] = registers[i];
50 // If a representations array is specified, then the descriptor owns that as
52 if (register_param_representations != NULL) {
53 register_param_representations_.Reset(
54 NewArray<Representation>(register_parameter_count));
55 for (int i = 0; i < register_parameter_count; i++) {
56 // If there is a context register, the representation must be tagged.
57 DCHECK(i != 0 || register_param_representations[i].Equals(
58 Representation::Tagged()));
59 register_param_representations_[i] = register_param_representations[i];
65 void CodeStubInterfaceDescriptor::Initialize(
66 CodeStub::Major major, int register_parameter_count, Register* registers,
67 Address deoptimization_handler,
68 Representation* register_param_representations,
69 int hint_stack_parameter_count, StubFunctionMode function_mode) {
70 InterfaceDescriptor::Initialize(register_parameter_count, registers,
71 register_param_representations);
73 deoptimization_handler_ = deoptimization_handler;
75 hint_stack_parameter_count_ = hint_stack_parameter_count;
76 function_mode_ = function_mode;
81 void CodeStubInterfaceDescriptor::Initialize(
82 CodeStub::Major major, int register_parameter_count, Register* registers,
83 Register stack_parameter_count, Address deoptimization_handler,
84 Representation* register_param_representations,
85 int hint_stack_parameter_count, StubFunctionMode function_mode,
86 HandlerArgumentsMode handler_mode) {
87 Initialize(major, register_parameter_count, registers, deoptimization_handler,
88 register_param_representations, hint_stack_parameter_count,
90 stack_parameter_count_ = stack_parameter_count;
91 handler_arguments_mode_ = handler_mode;
95 void CallInterfaceDescriptor::Initialize(
96 int register_parameter_count,
98 Representation* param_representations,
99 PlatformInterfaceDescriptor* platform_descriptor) {
100 InterfaceDescriptor::Initialize(register_parameter_count, registers,
101 param_representations, platform_descriptor);
105 bool CodeStub::FindCodeInCache(Code** code_out) {
106 UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
107 int index = stubs->FindEntry(GetKey());
108 if (index != UnseededNumberDictionary::kNotFound) {
109 *code_out = Code::cast(stubs->ValueAt(index));
116 void CodeStub::RecordCodeGeneration(Handle<Code> code) {
117 IC::RegisterWeakMapDependency(code);
120 PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, os.c_str()));
121 Counters* counters = isolate()->counters();
122 counters->total_stubs_code_size()->Increment(code->instruction_size());
126 Code::Kind CodeStub::GetCodeKind() const {
131 Handle<Code> CodeStub::GetCodeCopy(const Code::FindAndReplacePattern& pattern) {
132 Handle<Code> ic = GetCode();
133 ic = isolate()->factory()->CopyCode(ic);
134 ic->FindAndReplace(pattern);
135 RecordCodeGeneration(ic);
140 Handle<Code> PlatformCodeStub::GenerateCode() {
141 Factory* factory = isolate()->factory();
143 // Generate the new code.
144 MacroAssembler masm(isolate(), NULL, 256);
146 // TODO(yangguo) remove this once the code serializer handles code stubs.
147 if (FLAG_serialize_toplevel) masm.enable_serializer();
150 // Update the static counter each time a new code stub is generated.
151 isolate()->counters()->code_stubs()->Increment();
153 // Generate the code for the stub.
154 masm.set_generating_stub(true);
155 NoCurrentFrameScope scope(&masm);
159 // Create the code object.
163 // Copy the generated code into a heap object.
164 Code::Flags flags = Code::ComputeFlags(
169 Handle<Code> new_object = factory->NewCode(
170 desc, flags, masm.CodeObject(), NeedsImmovableCode());
175 Handle<Code> CodeStub::GetCode() {
176 Heap* heap = isolate()->heap();
178 if (UseSpecialCache()
179 ? FindCodeInSpecialCache(&code)
180 : FindCodeInCache(&code)) {
181 DCHECK(GetCodeKind() == code->kind());
182 return Handle<Code>(code);
186 HandleScope scope(isolate());
188 Handle<Code> new_object = GenerateCode();
189 new_object->set_stub_key(GetKey());
190 FinishCode(new_object);
191 RecordCodeGeneration(new_object);
193 #ifdef ENABLE_DISASSEMBLER
194 if (FLAG_print_code_stubs) {
195 CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
196 OFStream os(trace_scope.file());
199 new_object->Disassemble(name.c_str(), os);
204 if (UseSpecialCache()) {
205 AddToSpecialCache(new_object);
207 // Update the dictionary and the root in Heap.
208 Handle<UnseededNumberDictionary> dict =
209 UnseededNumberDictionary::AtNumberPut(
210 Handle<UnseededNumberDictionary>(heap->code_stubs()),
213 heap->public_set_code_stubs(*dict);
219 DCHECK(!NeedsImmovableCode() ||
220 heap->lo_space()->Contains(code) ||
221 heap->code_space()->FirstPage()->Contains(code->address()));
222 return Handle<Code>(code, isolate());
226 const char* CodeStub::MajorName(CodeStub::Major major_key,
227 bool allow_unknown_keys) {
229 #define DEF_CASE(name) case name: return #name "Stub";
230 CODE_STUB_LIST(DEF_CASE)
232 case UninitializedMajorKey: return "<UninitializedMajorKey>Stub";
234 return "<NoCache>Stub";
236 if (!allow_unknown_keys) {
244 void CodeStub::PrintBaseName(OStream& os) const { // NOLINT
245 os << MajorName(MajorKey(), false);
249 void CodeStub::PrintName(OStream& os) const { // NOLINT
256 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
257 // Generate the uninitialized versions of the stub.
258 for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
259 for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
260 BinaryOpICStub stub(isolate,
261 static_cast<Token::Value>(op),
262 static_cast<OverwriteMode>(mode));
267 // Generate special versions of the stub.
268 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
272 void BinaryOpICStub::PrintState(OStream& os) const { // NOLINT
278 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
279 const BinaryOpIC::State& state) {
280 BinaryOpICStub stub(isolate, state);
286 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
287 // Generate special versions of the stub.
288 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
292 void BinaryOpICWithAllocationSiteStub::PrintState(
293 OStream& os) const { // NOLINT
299 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
300 Isolate* isolate, const BinaryOpIC::State& state) {
301 if (state.CouldCreateAllocationMementos()) {
302 BinaryOpICWithAllocationSiteStub stub(isolate, state);
308 void StringAddStub::PrintBaseName(OStream& os) const { // NOLINT
309 os << "StringAddStub";
310 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
312 } else if ((flags() & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
314 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
317 if (pretenure_flag() == TENURED) {
323 InlineCacheState ICCompareStub::GetICState() const {
324 CompareIC::State state = Max(left_, right_);
326 case CompareIC::UNINITIALIZED:
327 return ::v8::internal::UNINITIALIZED;
329 case CompareIC::NUMBER:
330 case CompareIC::INTERNALIZED_STRING:
331 case CompareIC::STRING:
332 case CompareIC::UNIQUE_NAME:
333 case CompareIC::OBJECT:
334 case CompareIC::KNOWN_OBJECT:
336 case CompareIC::GENERIC:
337 return ::v8::internal::GENERIC;
340 return ::v8::internal::UNINITIALIZED;
344 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
345 DCHECK(*known_map_ != NULL);
346 Isolate* isolate = new_object->GetIsolate();
347 Factory* factory = isolate->factory();
348 return Map::UpdateCodeCache(known_map_,
350 factory->strict_compare_ic_string() :
351 factory->compare_ic_string(),
356 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) {
357 Factory* factory = isolate()->factory();
358 Code::Flags flags = Code::ComputeFlags(
361 DCHECK(op_ == Token::EQ || op_ == Token::EQ_STRICT);
362 Handle<Object> probe(
363 known_map_->FindInCodeCache(
365 *factory->strict_compare_ic_string() :
366 *factory->compare_ic_string(),
369 if (probe->IsCode()) {
370 *code_out = Code::cast(*probe);
372 Token::Value cached_op;
373 ICCompareStub::DecodeKey((*code_out)->stub_key(), NULL, NULL, NULL,
375 DCHECK(op_ == cached_op);
383 int ICCompareStub::MinorKey() const {
384 return OpField::encode(op_ - Token::EQ) |
385 LeftStateField::encode(left_) |
386 RightStateField::encode(right_) |
387 HandlerStateField::encode(state_);
391 void ICCompareStub::DecodeKey(uint32_t stub_key, CompareIC::State* left_state,
392 CompareIC::State* right_state,
393 CompareIC::State* handler_state,
395 int minor_key = MinorKeyFromKey(stub_key);
398 static_cast<CompareIC::State>(LeftStateField::decode(minor_key));
402 static_cast<CompareIC::State>(RightStateField::decode(minor_key));
406 static_cast<CompareIC::State>(HandlerStateField::decode(minor_key));
409 *op = static_cast<Token::Value>(OpField::decode(minor_key) + Token::EQ);
414 void ICCompareStub::Generate(MacroAssembler* masm) {
416 case CompareIC::UNINITIALIZED:
422 case CompareIC::NUMBER:
423 GenerateNumbers(masm);
425 case CompareIC::STRING:
426 GenerateStrings(masm);
428 case CompareIC::INTERNALIZED_STRING:
429 GenerateInternalizedStrings(masm);
431 case CompareIC::UNIQUE_NAME:
432 GenerateUniqueNames(masm);
434 case CompareIC::OBJECT:
435 GenerateObjects(masm);
437 case CompareIC::KNOWN_OBJECT:
438 DCHECK(*known_map_ != NULL);
439 GenerateKnownObjects(masm);
441 case CompareIC::GENERIC:
442 GenerateGeneric(masm);
448 void CompareNilICStub::UpdateStatus(Handle<Object> object) {
449 DCHECK(!state_.Contains(GENERIC));
450 State old_state(state_);
451 if (object->IsNull()) {
452 state_.Add(NULL_TYPE);
453 } else if (object->IsUndefined()) {
454 state_.Add(UNDEFINED);
455 } else if (object->IsUndetectableObject() ||
456 object->IsOddball() ||
457 !object->IsHeapObject()) {
460 } else if (IsMonomorphic()) {
464 state_.Add(MONOMORPHIC_MAP);
466 TraceTransition(old_state, state_);
470 template<class StateType>
471 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
472 // Note: Although a no-op transition is semantically OK, it is hinting at a
473 // bug somewhere in our state transition machinery.
475 if (!FLAG_trace_ic) return;
479 os << ": " << from << "=>" << to << "]" << endl;
483 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT
484 CodeStub::PrintBaseName(os);
485 os << ((nil_value_ == kNullValue) ? "(NullValue)" : "(UndefinedValue)");
489 void CompareNilICStub::PrintState(OStream& os) const { // NOLINT
494 // TODO(svenpanne) Make this a real infix_ostream_iterator.
495 class SimpleListPrinter {
497 explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {}
499 void Add(const char* s) {
514 OStream& operator<<(OStream& os, const CompareNilICStub::State& s) {
516 SimpleListPrinter p(os);
517 if (s.IsEmpty()) p.Add("None");
518 if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined");
519 if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null");
520 if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap");
521 if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic");
526 Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) {
527 if (state_.Contains(CompareNilICStub::GENERIC)) {
528 return Type::Any(zone);
531 Type* result = Type::None(zone);
532 if (state_.Contains(CompareNilICStub::UNDEFINED)) {
533 result = Type::Union(result, Type::Undefined(zone), zone);
535 if (state_.Contains(CompareNilICStub::NULL_TYPE)) {
536 result = Type::Union(result, Type::Null(zone), zone);
538 if (state_.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
540 map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone);
541 result = Type::Union(result, type, zone);
548 Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) {
549 Type* output_type = GetType(zone, map);
551 nil_value_ == kNullValue ? Type::Null(zone) : Type::Undefined(zone);
552 return Type::Union(output_type, nil_type, zone);
556 void CallIC_ArrayStub::PrintState(OStream& os) const { // NOLINT
557 os << state_ << " (Array)";
561 void CallICStub::PrintState(OStream& os) const { // NOLINT
566 void InstanceofStub::PrintName(OStream& os) const { // NOLINT
567 os << "InstanceofStub";
568 if (HasArgsInRegisters()) os << "_REGS";
569 if (HasCallSiteInlineCheck()) os << "_INLINE";
570 if (ReturnTrueFalseObject()) os << "_TRUEFALSE";
574 void JSEntryStub::FinishCode(Handle<Code> code) {
575 Handle<FixedArray> handler_table =
576 code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
577 handler_table->set(0, Smi::FromInt(handler_offset_));
578 code->set_handler_table(*handler_table);
582 void LoadFastElementStub::InitializeInterfaceDescriptor(
583 CodeStubInterfaceDescriptor* descriptor) {
584 Register registers[] = { InterfaceDescriptor::ContextRegister(),
585 LoadIC::ReceiverRegister(),
586 LoadIC::NameRegister() };
587 STATIC_ASSERT(LoadIC::kParameterCount == 2);
588 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
589 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
593 void LoadDictionaryElementStub::InitializeInterfaceDescriptor(
594 CodeStubInterfaceDescriptor* descriptor) {
595 Register registers[] = { InterfaceDescriptor::ContextRegister(),
596 LoadIC::ReceiverRegister(),
597 LoadIC::NameRegister() };
598 STATIC_ASSERT(LoadIC::kParameterCount == 2);
599 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
600 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
604 void KeyedLoadGenericStub::InitializeInterfaceDescriptor(
605 CodeStubInterfaceDescriptor* descriptor) {
606 Register registers[] = { InterfaceDescriptor::ContextRegister(),
607 LoadIC::ReceiverRegister(),
608 LoadIC::NameRegister() };
609 STATIC_ASSERT(LoadIC::kParameterCount == 2);
610 descriptor->Initialize(
611 MajorKey(), ARRAY_SIZE(registers), registers,
612 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry);
616 void HandlerStub::InitializeInterfaceDescriptor(
617 CodeStubInterfaceDescriptor* descriptor) {
618 if (kind() == Code::LOAD_IC) {
619 Register registers[] = {InterfaceDescriptor::ContextRegister(),
620 LoadIC::ReceiverRegister(), LoadIC::NameRegister()};
621 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
623 DCHECK_EQ(Code::STORE_IC, kind());
624 Register registers[] = {InterfaceDescriptor::ContextRegister(),
625 StoreIC::ReceiverRegister(),
626 StoreIC::NameRegister(), StoreIC::ValueRegister()};
627 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
628 FUNCTION_ADDR(StoreIC_MissFromStubFailure));
633 void StoreFastElementStub::InitializeInterfaceDescriptor(
634 CodeStubInterfaceDescriptor* descriptor) {
635 Register registers[] = { InterfaceDescriptor::ContextRegister(),
636 KeyedStoreIC::ReceiverRegister(),
637 KeyedStoreIC::NameRegister(),
638 KeyedStoreIC::ValueRegister() };
639 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
640 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
644 void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
645 CodeStubInterfaceDescriptor* descriptor) {
646 Register registers[] = { InterfaceDescriptor::ContextRegister(),
651 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
652 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
656 void InstanceofStub::InitializeInterfaceDescriptor(
657 CodeStubInterfaceDescriptor* descriptor) {
658 Register registers[] = { InterfaceDescriptor::ContextRegister(),
659 InstanceofStub::left(),
660 InstanceofStub::right() };
661 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
665 void LoadDictionaryElementPlatformStub::Generate(MacroAssembler* masm) {
666 ElementHandlerCompiler::GenerateLoadDictionaryElement(masm);
670 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
671 CreateAllocationSiteStub stub(isolate);
676 void StoreElementStub::Generate(MacroAssembler* masm) {
677 switch (elements_kind_) {
679 case FAST_HOLEY_ELEMENTS:
680 case FAST_SMI_ELEMENTS:
681 case FAST_HOLEY_SMI_ELEMENTS:
682 case FAST_DOUBLE_ELEMENTS:
683 case FAST_HOLEY_DOUBLE_ELEMENTS:
684 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
685 case EXTERNAL_##TYPE##_ELEMENTS: \
686 case TYPE##_ELEMENTS:
688 TYPED_ARRAYS(TYPED_ARRAY_CASE)
689 #undef TYPED_ARRAY_CASE
692 case DICTIONARY_ELEMENTS:
693 ElementHandlerCompiler::GenerateStoreDictionaryElement(masm);
695 case SLOPPY_ARGUMENTS_ELEMENTS:
702 void ArgumentsAccessStub::PrintName(OStream& os) const { // NOLINT
703 os << "ArgumentsAccessStub_";
708 case NEW_SLOPPY_FAST:
709 os << "NewSloppyFast";
711 case NEW_SLOPPY_SLOW:
712 os << "NewSloppySlow";
722 void CallFunctionStub::PrintName(OStream& os) const { // NOLINT
723 os << "CallFunctionStub_Args" << argc_;
727 void CallConstructStub::PrintName(OStream& os) const { // NOLINT
728 os << "CallConstructStub";
729 if (RecordCallTarget()) os << "_Recording";
733 void ArrayConstructorStub::PrintName(OStream& os) const { // NOLINT
734 os << "ArrayConstructorStub";
735 switch (argument_count_) {
746 os << "_More_Than_One";
753 OStream& ArrayConstructorStubBase::BasePrintName(OStream& os, // NOLINT
754 const char* name) const {
755 os << name << "_" << ElementsKindToString(elements_kind());
756 if (override_mode() == DISABLE_ALLOCATION_SITES) {
757 os << "_DISABLE_ALLOCATION_SITES";
763 bool ToBooleanStub::UpdateStatus(Handle<Object> object) {
764 Types old_types(types_);
765 bool to_boolean_value = types_.UpdateStatus(object);
766 TraceTransition(old_types, types_);
767 return to_boolean_value;
771 void ToBooleanStub::PrintState(OStream& os) const { // NOLINT
776 OStream& operator<<(OStream& os, const ToBooleanStub::Types& s) {
778 SimpleListPrinter p(os);
779 if (s.IsEmpty()) p.Add("None");
780 if (s.Contains(ToBooleanStub::UNDEFINED)) p.Add("Undefined");
781 if (s.Contains(ToBooleanStub::BOOLEAN)) p.Add("Bool");
782 if (s.Contains(ToBooleanStub::NULL_TYPE)) p.Add("Null");
783 if (s.Contains(ToBooleanStub::SMI)) p.Add("Smi");
784 if (s.Contains(ToBooleanStub::SPEC_OBJECT)) p.Add("SpecObject");
785 if (s.Contains(ToBooleanStub::STRING)) p.Add("String");
786 if (s.Contains(ToBooleanStub::SYMBOL)) p.Add("Symbol");
787 if (s.Contains(ToBooleanStub::HEAP_NUMBER)) p.Add("HeapNumber");
792 bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) {
793 if (object->IsUndefined()) {
796 } else if (object->IsBoolean()) {
798 return object->IsTrue();
799 } else if (object->IsNull()) {
802 } else if (object->IsSmi()) {
804 return Smi::cast(*object)->value() != 0;
805 } else if (object->IsSpecObject()) {
807 return !object->IsUndetectableObject();
808 } else if (object->IsString()) {
810 return !object->IsUndetectableObject() &&
811 String::cast(*object)->length() != 0;
812 } else if (object->IsSymbol()) {
815 } else if (object->IsHeapNumber()) {
816 DCHECK(!object->IsUndetectableObject());
818 double value = HeapNumber::cast(*object)->value();
819 return value != 0 && !std::isnan(value);
821 // We should never see an internal object at runtime here!
828 bool ToBooleanStub::Types::NeedsMap() const {
829 return Contains(ToBooleanStub::SPEC_OBJECT)
830 || Contains(ToBooleanStub::STRING)
831 || Contains(ToBooleanStub::SYMBOL)
832 || Contains(ToBooleanStub::HEAP_NUMBER);
836 bool ToBooleanStub::Types::CanBeUndetectable() const {
837 return Contains(ToBooleanStub::SPEC_OBJECT)
838 || Contains(ToBooleanStub::STRING);
842 void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
843 StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE);
844 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE);
850 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
851 intptr_t stack_pointer,
853 FunctionEntryHook entry_hook = isolate->function_entry_hook();
854 DCHECK(entry_hook != NULL);
855 entry_hook(function, stack_pointer);
859 static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) {
860 int major_key = stub->MajorKey();
861 CodeStubInterfaceDescriptor* descriptor =
862 isolate->code_stub_interface_descriptor(major_key);
863 if (!descriptor->IsInitialized()) {
864 stub->InitializeInterfaceDescriptor(descriptor);
869 void ArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
870 ArrayNoArgumentConstructorStub stub1(isolate, GetInitialFastElementsKind());
871 InstallDescriptor(isolate, &stub1);
872 ArraySingleArgumentConstructorStub stub2(isolate,
873 GetInitialFastElementsKind());
874 InstallDescriptor(isolate, &stub2);
875 ArrayNArgumentsConstructorStub stub3(isolate, GetInitialFastElementsKind());
876 InstallDescriptor(isolate, &stub3);
880 void NumberToStringStub::InstallDescriptors(Isolate* isolate) {
881 NumberToStringStub stub(isolate);
882 InstallDescriptor(isolate, &stub);
886 void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
887 FastNewClosureStub stub(isolate, STRICT, false);
888 InstallDescriptor(isolate, &stub);
892 void FastNewContextStub::InstallDescriptors(Isolate* isolate) {
893 FastNewContextStub stub(isolate, FastNewContextStub::kMaximumSlots);
894 InstallDescriptor(isolate, &stub);
899 void FastCloneShallowArrayStub::InstallDescriptors(Isolate* isolate) {
900 FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE);
901 InstallDescriptor(isolate, &stub);
906 void BinaryOpICStub::InstallDescriptors(Isolate* isolate) {
907 BinaryOpICStub stub(isolate, Token::ADD, NO_OVERWRITE);
908 InstallDescriptor(isolate, &stub);
913 void BinaryOpWithAllocationSiteStub::InstallDescriptors(Isolate* isolate) {
914 BinaryOpWithAllocationSiteStub stub(isolate, Token::ADD, NO_OVERWRITE);
915 InstallDescriptor(isolate, &stub);
920 void StringAddStub::InstallDescriptors(Isolate* isolate) {
921 StringAddStub stub(isolate, STRING_ADD_CHECK_NONE, NOT_TENURED);
922 InstallDescriptor(isolate, &stub);
927 void RegExpConstructResultStub::InstallDescriptors(Isolate* isolate) {
928 RegExpConstructResultStub stub(isolate);
929 InstallDescriptor(isolate, &stub);
934 void KeyedLoadGenericStub::InstallDescriptors(Isolate* isolate) {
935 KeyedLoadGenericStub stub(isolate);
936 InstallDescriptor(isolate, &stub);
941 void StoreFieldStub::InstallDescriptors(Isolate* isolate) {
942 StoreFieldStub stub(isolate, FieldIndex::ForInObjectOffset(0),
943 Representation::None());
944 InstallDescriptor(isolate, &stub);
948 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
949 : PlatformCodeStub(isolate), argument_count_(ANY) {
950 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
954 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate,
956 : PlatformCodeStub(isolate) {
957 if (argument_count == 0) {
958 argument_count_ = NONE;
959 } else if (argument_count == 1) {
960 argument_count_ = ONE;
961 } else if (argument_count >= 2) {
962 argument_count_ = MORE_THAN_ONE;
966 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
970 void InternalArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
971 InternalArrayNoArgumentConstructorStub stub1(isolate, FAST_ELEMENTS);
972 InstallDescriptor(isolate, &stub1);
973 InternalArraySingleArgumentConstructorStub stub2(isolate, FAST_ELEMENTS);
974 InstallDescriptor(isolate, &stub2);
975 InternalArrayNArgumentsConstructorStub stub3(isolate, FAST_ELEMENTS);
976 InstallDescriptor(isolate, &stub3);
979 InternalArrayConstructorStub::InternalArrayConstructorStub(
980 Isolate* isolate) : PlatformCodeStub(isolate) {
981 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
985 } } // namespace v8::internal