5 #include "src/code-stubs.h" 9 #include "src/arguments.h" 10 #include "src/assembler-inl.h" 11 #include "src/ast/ast.h" 12 #include "src/bootstrapper.h" 13 #include "src/code-factory.h" 14 #include "src/code-stubs-utils.h" 15 #include "src/code-tracer.h" 16 #include "src/counters.h" 17 #include "src/gdb-jit.h" 18 #include "src/heap/heap-inl.h" 19 #include "src/ic/ic-stats.h" 20 #include "src/ic/ic.h" 21 #include "src/macro-assembler.h" 22 #include "src/objects-inl.h" 23 #include "src/objects/hash-table-inl.h" 24 #include "src/tracing/tracing-category-observer.h" 29 using compiler::CodeAssemblerState;
31 CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub)
32 : isolate_(stub->isolate()),
33 call_descriptor_(stub->GetCallInterfaceDescriptor()),
34 stack_parameter_count_(no_reg),
35 hint_stack_parameter_count_(-1),
36 function_mode_(NOT_JS_FUNCTION_STUB_MODE),
37 deoptimization_handler_(kNullAddress),
39 has_miss_handler_(false) {}
41 CodeStubDescriptor::CodeStubDescriptor(Isolate* isolate,
uint32_t stub_key)
43 stack_parameter_count_(no_reg),
44 hint_stack_parameter_count_(-1),
45 function_mode_(NOT_JS_FUNCTION_STUB_MODE),
46 deoptimization_handler_(kNullAddress),
48 has_miss_handler_(false) {
49 CodeStub::InitializeDescriptor(isolate, stub_key,
this);
53 void CodeStubDescriptor::Initialize(Address deoptimization_handler,
54 int hint_stack_parameter_count,
55 StubFunctionMode function_mode) {
56 deoptimization_handler_ = deoptimization_handler;
57 hint_stack_parameter_count_ = hint_stack_parameter_count;
58 function_mode_ = function_mode;
62 void CodeStubDescriptor::Initialize(Register stack_parameter_count,
63 Address deoptimization_handler,
64 int hint_stack_parameter_count,
65 StubFunctionMode function_mode) {
66 Initialize(deoptimization_handler, hint_stack_parameter_count, function_mode);
67 stack_parameter_count_ = stack_parameter_count;
70 bool CodeStub::FindCodeInCache(Code* code_out) {
71 SimpleNumberDictionary stubs = isolate()->heap()->code_stubs();
72 int index = stubs->FindEntry(isolate(), GetKey());
73 if (index != SimpleNumberDictionary::kNotFound) {
74 *code_out = Code::cast(stubs->ValueAt(index));
81 void CodeStub::RecordCodeGeneration(Handle<Code> code) {
82 std::ostringstream os;
85 CodeCreateEvent(CodeEventListener::STUB_TAG,
86 AbstractCode::cast(*code), os.str().c_str()));
87 Counters* counters = isolate()->counters();
88 counters->total_stubs_code_size()->Increment(code->raw_instruction_size());
90 code->VerifyEmbeddedObjects(isolate());
95 void CodeStub::DeleteStubFromCacheForTesting() {
96 Heap* heap = isolate_->heap();
97 Handle<SimpleNumberDictionary> dict(heap->code_stubs(), isolate());
98 int entry = dict->FindEntry(isolate(), GetKey());
99 DCHECK_NE(SimpleNumberDictionary::kNotFound, entry);
100 dict = SimpleNumberDictionary::DeleteEntry(isolate(), dict, entry);
101 heap->SetRootCodeStubs(*dict);
104 Handle<Code> PlatformCodeStub::GenerateCode() {
105 Factory* factory = isolate()->factory();
109 AssemblerOptions options = AssemblerOptions::Default(isolate(),
true);
110 MacroAssembler masm(isolate(), options,
nullptr, 256,
111 CodeObjectRequired::kYes);
115 isolate()->counters()->code_stubs()->Increment();
118 NoCurrentFrameScope scope(&masm);
123 int handler_table_offset = GenerateHandlerTable(&masm);
127 masm.GetCode(isolate(), &desc);
129 Handle<Code> new_object = factory->NewCode(
130 desc, Code::STUB, masm.CodeObject(), Builtins::kNoBuiltinId,
131 MaybeHandle<ByteArray>(), DeoptimizationData::Empty(isolate()),
132 NeedsImmovableCode(), GetKey(),
false, 0, 0, handler_table_offset);
137 Handle<Code> CodeStub::GetCode() {
138 Heap* heap = isolate()->heap();
140 if (FindCodeInCache(&code)) {
141 DCHECK(code->is_stub());
142 return handle(code, isolate_);
146 HandleScope scope(isolate());
149 CanonicalHandleScope canonical(isolate());
151 Handle<Code> new_object = GenerateCode();
152 DCHECK_EQ(GetKey(), new_object->stub_key());
153 RecordCodeGeneration(new_object);
155 #ifdef ENABLE_DISASSEMBLER 156 if (FLAG_print_code_stubs) {
157 CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
158 OFStream os(trace_scope.file());
159 std::ostringstream name;
161 new_object->Disassemble(name.str().c_str(), os);
167 Handle<SimpleNumberDictionary> dict = SimpleNumberDictionary::Set(
168 isolate(), handle(heap->code_stubs(), isolate_), GetKey(), new_object);
169 heap->SetRootCodeStubs(*dict);
173 DCHECK(!NeedsImmovableCode() || heap->IsImmovable(code));
174 return Handle<Code>(code, isolate());
177 CodeStub::Major CodeStub::GetMajorKey(
const Code code_stub) {
178 return MajorKeyFromKey(code_stub->stub_key());
181 const char* CodeStub::MajorName(CodeStub::Major major_key) {
183 #define DEF_CASE(name) case name: return #name "Stub"; 184 CODE_STUB_LIST(DEF_CASE)
187 return "<NoCache>Stub";
195 void CodeStub::PrintBaseName(std::ostream& os)
const {
196 os << MajorName(MajorKey());
200 void CodeStub::PrintName(std::ostream& os)
const {
206 void CodeStub::Dispatch(Isolate* isolate,
uint32_t key,
void** value_out,
207 DispatchedCall call) {
208 switch (MajorKeyFromKey(key)) {
209 #define DEF_CASE(NAME) \ 211 NAME##Stub stub(key, isolate); \ 212 CodeStub* pstub = &stub; \ 213 call(pstub, value_out); \ 216 CODE_STUB_LIST(DEF_CASE)
225 int PlatformCodeStub::GenerateHandlerTable(MacroAssembler* masm) {
return 0; }
227 static void InitializeDescriptorDispatchedCall(CodeStub* stub,
229 CodeStubDescriptor* descriptor_out =
230 reinterpret_cast<CodeStubDescriptor*
>(value_out);
231 descriptor_out->set_call_descriptor(stub->GetCallInterfaceDescriptor());
235 void CodeStub::InitializeDescriptor(Isolate* isolate,
uint32_t key,
236 CodeStubDescriptor* desc) {
237 void** value_out =
reinterpret_cast<void**
>(desc);
238 Dispatch(isolate, key, value_out, &InitializeDescriptorDispatchedCall);
242 void CodeStub::GetCodeDispatchCall(CodeStub* stub,
void** value_out) {
243 Handle<Code>* code_out =
reinterpret_cast<Handle<Code>*
>(value_out);
244 *code_out = stub->GetCode();
248 MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate,
uint32_t key) {
249 HandleScope scope(isolate);
251 void** value_out =
reinterpret_cast<void**
>(&code);
252 Dispatch(isolate, key, value_out, &GetCodeDispatchCall);
253 return scope.CloseAndEscape(code);
256 int JSEntryStub::GenerateHandlerTable(MacroAssembler* masm) {
257 int handler_table_offset = HandlerTable::EmitReturnTableStart(masm, 1);
258 HandlerTable::EmitReturnEntry(masm, 0, handler_offset_);
259 return handler_table_offset;