blob: 4e5efcd8e02bd115a9c303cba78619d552a07198 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include "src/code-stubs.h"
6
7#include <sstream>
Steve Blocka7e24c12009-10-30 11:49:00 +00008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/bootstrapper.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/compiler/code-stub-assembler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/factory.h"
12#include "src/gdb-jit.h"
13#include "src/ic/handler-compiler.h"
14#include "src/ic/ic.h"
15#include "src/macro-assembler.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000016#include "src/parsing/parser.h"
17#include "src/profiler/cpu-profiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000018
19namespace v8 {
20namespace internal {
21
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023RUNTIME_FUNCTION(UnexpectedStubMiss) {
24 FATAL("Unexpected deopt of a stub");
25 return Smi::FromInt(0);
26}
27
28
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029CodeStubDescriptor::CodeStubDescriptor(CodeStub* stub)
30 : call_descriptor_(stub->GetCallInterfaceDescriptor()),
31 stack_parameter_count_(no_reg),
32 hint_stack_parameter_count_(-1),
33 function_mode_(NOT_JS_FUNCTION_STUB_MODE),
34 deoptimization_handler_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 miss_handler_(),
36 has_miss_handler_(false) {
37 stub->InitializeDescriptor(this);
38}
39
40
41CodeStubDescriptor::CodeStubDescriptor(Isolate* isolate, uint32_t stub_key)
42 : stack_parameter_count_(no_reg),
43 hint_stack_parameter_count_(-1),
44 function_mode_(NOT_JS_FUNCTION_STUB_MODE),
45 deoptimization_handler_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046 miss_handler_(),
47 has_miss_handler_(false) {
48 CodeStub::InitializeDescriptor(isolate, stub_key, this);
49}
50
51
52void CodeStubDescriptor::Initialize(Address deoptimization_handler,
53 int hint_stack_parameter_count,
54 StubFunctionMode function_mode) {
55 deoptimization_handler_ = deoptimization_handler;
56 hint_stack_parameter_count_ = hint_stack_parameter_count;
57 function_mode_ = function_mode;
58}
59
60
61void CodeStubDescriptor::Initialize(Register stack_parameter_count,
62 Address deoptimization_handler,
63 int hint_stack_parameter_count,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 StubFunctionMode function_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065 Initialize(deoptimization_handler, hint_stack_parameter_count, function_mode);
66 stack_parameter_count_ = stack_parameter_count;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067}
68
69
Leon Clarkee46be812010-01-19 14:06:41 +000070bool CodeStub::FindCodeInCache(Code** code_out) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
72 int index = stubs->FindEntry(GetKey());
Ben Murdochc7cc0282012-03-05 14:35:55 +000073 if (index != UnseededNumberDictionary::kNotFound) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074 *code_out = Code::cast(stubs->ValueAt(index));
Leon Clarkee46be812010-01-19 14:06:41 +000075 return true;
Steve Blockd0582a62009-12-15 09:54:21 +000076 }
Leon Clarkee46be812010-01-19 14:06:41 +000077 return false;
78}
Steve Blockd0582a62009-12-15 09:54:21 +000079
Leon Clarkee46be812010-01-19 14:06:41 +000080
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081void CodeStub::RecordCodeGeneration(Handle<Code> code) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040082 std::ostringstream os;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 os << *this;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040084 PROFILE(isolate(),
85 CodeCreateEvent(Logger::STUB_TAG, *code, os.str().c_str()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086 Counters* counters = isolate()->counters();
Steve Block44f0eee2011-05-26 01:26:41 +010087 counters->total_stubs_code_size()->Increment(code->instruction_size());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088#ifdef DEBUG
89 code->VerifyEmbeddedObjects();
90#endif
Leon Clarkee46be812010-01-19 14:06:41 +000091}
92
93
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094Code::Kind CodeStub::GetCodeKind() const {
Steve Block6ded16b2010-05-10 14:33:55 +010095 return Code::STUB;
96}
97
98
Ben Murdoch097c5b22016-05-18 11:27:45 +010099Code::Flags CodeStub::GetCodeFlags() const {
100 return Code::ComputeFlags(GetCodeKind(), GetICState(), GetExtraICState(),
101 GetStubType());
102}
103
104
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105Handle<Code> CodeStub::GetCodeCopy(const Code::FindAndReplacePattern& pattern) {
106 Handle<Code> ic = GetCode();
107 ic = isolate()->factory()->CopyCode(ic);
108 ic->FindAndReplace(pattern);
109 RecordCodeGeneration(ic);
110 return ic;
111}
112
113
114Handle<Code> PlatformCodeStub::GenerateCode() {
115 Factory* factory = isolate()->factory();
116
117 // Generate the new code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 MacroAssembler masm(isolate(), NULL, 256, CodeObjectRequired::kYes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 {
121 // Update the static counter each time a new code stub is generated.
122 isolate()->counters()->code_stubs()->Increment();
123
124 // Generate the code for the stub.
125 masm.set_generating_stub(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400126 // TODO(yangguo): remove this once we can serialize IC stubs.
127 masm.enable_serializer();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128 NoCurrentFrameScope scope(&masm);
129 Generate(&masm);
130 }
131
132 // Create the code object.
133 CodeDesc desc;
134 masm.GetCode(&desc);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 // Copy the generated code into a heap object.
136 Code::Flags flags = Code::ComputeFlags(
137 GetCodeKind(),
138 GetICState(),
139 GetExtraICState(),
140 GetStubType());
141 Handle<Code> new_object = factory->NewCode(
142 desc, flags, masm.CodeObject(), NeedsImmovableCode());
143 return new_object;
144}
145
146
Leon Clarkee46be812010-01-19 14:06:41 +0000147Handle<Code> CodeStub::GetCode() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148 Heap* heap = isolate()->heap();
Leon Clarkee46be812010-01-19 14:06:41 +0000149 Code* code;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 if (UseSpecialCache() ? FindCodeInSpecialCache(&code)
151 : FindCodeInCache(&code)) {
152 DCHECK(GetCodeKind() == code->kind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100153 return Handle<Code>(code);
154 }
155
156 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157 HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000158
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159 Handle<Code> new_object = GenerateCode();
160 new_object->set_stub_key(GetKey());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100161 FinishCode(new_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162 RecordCodeGeneration(new_object);
163
164#ifdef ENABLE_DISASSEMBLER
165 if (FLAG_print_code_stubs) {
166 CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
167 OFStream os(trace_scope.file());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168 std::ostringstream name;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 name << *this;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400170 new_object->Disassemble(name.str().c_str(), os);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171 os << "\n";
172 }
173#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000174
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100175 if (UseSpecialCache()) {
176 AddToSpecialCache(new_object);
177 } else {
178 // Update the dictionary and the root in Heap.
179 Handle<UnseededNumberDictionary> dict =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 UnseededNumberDictionary::AtNumberPut(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100181 Handle<UnseededNumberDictionary>(heap->code_stubs()),
182 GetKey(),
183 new_object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000184 heap->SetRootCodeStubs(*dict);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100185 }
Leon Clarkee46be812010-01-19 14:06:41 +0000186 code = *new_object;
Steve Blocka7e24c12009-10-30 11:49:00 +0000187 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000188
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100189 Activate(code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 DCHECK(!NeedsImmovableCode() ||
191 heap->lo_space()->Contains(code) ||
192 heap->code_space()->FirstPage()->Contains(code->address()));
193 return Handle<Code>(code, isolate());
Leon Clarkee46be812010-01-19 14:06:41 +0000194}
195
196
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197const char* CodeStub::MajorName(CodeStub::Major major_key) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000198 switch (major_key) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000199#define DEF_CASE(name) case name: return #name "Stub";
Steve Blockd0582a62009-12-15 09:54:21 +0000200 CODE_STUB_LIST(DEF_CASE)
201#undef DEF_CASE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202 case NoCache:
203 return "<NoCache>Stub";
204 case NUMBER_OF_IDS:
205 UNREACHABLE();
Steve Blocka7e24c12009-10-30 11:49:00 +0000206 return NULL;
207 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 return NULL;
209}
210
211
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400212void CodeStub::PrintBaseName(std::ostream& os) const { // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 os << MajorName(MajorKey());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000214}
215
216
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400217void CodeStub::PrintName(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218 PrintBaseName(os);
219 PrintState(os);
220}
221
222
223void CodeStub::Dispatch(Isolate* isolate, uint32_t key, void** value_out,
224 DispatchedCall call) {
225 switch (MajorKeyFromKey(key)) {
226#define DEF_CASE(NAME) \
227 case NAME: { \
228 NAME##Stub stub(key, isolate); \
229 CodeStub* pstub = &stub; \
230 call(pstub, value_out); \
231 break; \
232 }
233 CODE_STUB_LIST(DEF_CASE)
234#undef DEF_CASE
235 case NUMBER_OF_IDS:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 case NoCache:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400237 UNREACHABLE();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238 break;
239 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000240}
241
242
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243static void InitializeDescriptorDispatchedCall(CodeStub* stub,
244 void** value_out) {
245 CodeStubDescriptor* descriptor_out =
246 reinterpret_cast<CodeStubDescriptor*>(value_out);
247 stub->InitializeDescriptor(descriptor_out);
248 descriptor_out->set_call_descriptor(stub->GetCallInterfaceDescriptor());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100249}
250
251
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252void CodeStub::InitializeDescriptor(Isolate* isolate, uint32_t key,
253 CodeStubDescriptor* desc) {
254 void** value_out = reinterpret_cast<void**>(desc);
255 Dispatch(isolate, key, value_out, &InitializeDescriptorDispatchedCall);
256}
257
258
259void CodeStub::GetCodeDispatchCall(CodeStub* stub, void** value_out) {
260 Handle<Code>* code_out = reinterpret_cast<Handle<Code>*>(value_out);
261 // Code stubs with special cache cannot be recreated from stub key.
262 *code_out = stub->UseSpecialCache() ? Handle<Code>() : stub->GetCode();
263}
264
265
266MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
267 HandleScope scope(isolate);
268 Handle<Code> code;
269 void** value_out = reinterpret_cast<void**>(&code);
270 Dispatch(isolate, key, value_out, &GetCodeDispatchCall);
271 return scope.CloseAndEscape(code);
272}
273
274
275// static
276void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
277 // Generate the uninitialized versions of the stub.
278 for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100279 BinaryOpICStub stub(isolate, static_cast<Token::Value>(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280 stub.GetCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281 }
282
283 // Generate special versions of the stub.
284 BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
285}
286
287
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400288void BinaryOpICStub::PrintState(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000289 os << state();
290}
291
292
293// static
294void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
295 const BinaryOpICState& state) {
296 BinaryOpICStub stub(isolate, state);
297 stub.GetCode();
298}
299
300
301// static
302void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
303 // Generate special versions of the stub.
304 BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
305}
306
307
308void BinaryOpICWithAllocationSiteStub::PrintState(
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400309 std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310 os << state();
311}
312
313
314// static
315void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
316 Isolate* isolate, const BinaryOpICState& state) {
317 if (state.CouldCreateAllocationMementos()) {
318 BinaryOpICWithAllocationSiteStub stub(isolate, state);
319 stub.GetCode();
320 }
321}
322
323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags) {
325 switch (flags) {
326 case STRING_ADD_CHECK_NONE:
327 return os << "CheckNone";
328 case STRING_ADD_CHECK_LEFT:
329 return os << "CheckLeft";
330 case STRING_ADD_CHECK_RIGHT:
331 return os << "CheckRight";
332 case STRING_ADD_CHECK_BOTH:
333 return os << "CheckBoth";
334 case STRING_ADD_CONVERT_LEFT:
335 return os << "ConvertLeft";
336 case STRING_ADD_CONVERT_RIGHT:
337 return os << "ConvertRight";
338 case STRING_ADD_CONVERT:
339 break;
340 }
341 UNREACHABLE();
342 return os;
343}
344
345
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400346void StringAddStub::PrintBaseName(std::ostream& os) const { // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000347 os << "StringAddStub_" << flags() << "_" << pretenure_flag();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348}
349
350
351InlineCacheState CompareICStub::GetICState() const {
352 CompareICState::State state = Max(left(), right());
353 switch (state) {
354 case CompareICState::UNINITIALIZED:
355 return ::v8::internal::UNINITIALIZED;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000356 case CompareICState::BOOLEAN:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000357 case CompareICState::SMI:
358 case CompareICState::NUMBER:
359 case CompareICState::INTERNALIZED_STRING:
360 case CompareICState::STRING:
361 case CompareICState::UNIQUE_NAME:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362 case CompareICState::RECEIVER:
363 case CompareICState::KNOWN_RECEIVER:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000364 return MONOMORPHIC;
365 case CompareICState::GENERIC:
366 return ::v8::internal::GENERIC;
367 }
368 UNREACHABLE();
369 return ::v8::internal::UNINITIALIZED;
370}
371
372
373Condition CompareICStub::GetCondition() const {
374 return CompareIC::ComputeCondition(op());
375}
376
377
378void CompareICStub::AddToSpecialCache(Handle<Code> new_object) {
379 DCHECK(*known_map_ != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100380 Isolate* isolate = new_object->GetIsolate();
381 Factory* factory = isolate->factory();
382 return Map::UpdateCodeCache(known_map_,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000383 strict() ?
384 factory->strict_compare_ic_string() :
385 factory->compare_ic_string(),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100386 new_object);
387}
388
389
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000390bool CompareICStub::FindCodeInSpecialCache(Code** code_out) {
391 Factory* factory = isolate()->factory();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100392 Code::Flags flags = Code::ComputeFlags(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393 GetCodeKind(),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100394 UNINITIALIZED);
395 Handle<Object> probe(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000396 known_map_->FindInCodeCache(
397 strict() ?
398 *factory->strict_compare_ic_string() :
399 *factory->compare_ic_string(),
400 flags),
401 isolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100402 if (probe->IsCode()) {
403 *code_out = Code::cast(*probe);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000404#ifdef DEBUG
405 CompareICStub decode((*code_out)->stub_key(), isolate());
406 DCHECK(op() == decode.op());
407 DCHECK(left() == decode.left());
408 DCHECK(right() == decode.right());
409 DCHECK(state() == decode.state());
410#endif
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100411 return true;
412 }
413 return false;
414}
415
416
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000417void CompareICStub::Generate(MacroAssembler* masm) {
418 switch (state()) {
419 case CompareICState::UNINITIALIZED:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100420 GenerateMiss(masm);
421 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000422 case CompareICState::BOOLEAN:
423 GenerateBooleans(masm);
424 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 case CompareICState::SMI:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100426 GenerateSmis(masm);
427 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000428 case CompareICState::NUMBER:
429 GenerateNumbers(masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100430 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000431 case CompareICState::STRING:
Ben Murdoch257744e2011-11-30 15:57:28 +0000432 GenerateStrings(masm);
433 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434 case CompareICState::INTERNALIZED_STRING:
435 GenerateInternalizedStrings(masm);
Ben Murdoch257744e2011-11-30 15:57:28 +0000436 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437 case CompareICState::UNIQUE_NAME:
438 GenerateUniqueNames(masm);
439 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000440 case CompareICState::RECEIVER:
441 GenerateReceivers(masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100442 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 case CompareICState::KNOWN_RECEIVER:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000444 DCHECK(*known_map_ != NULL);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000445 GenerateKnownReceivers(masm);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100446 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000447 case CompareICState::GENERIC:
448 GenerateGeneric(masm);
449 break;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100450 }
451}
452
453
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000454void CompareNilICStub::UpdateStatus(Handle<Object> object) {
455 State state = this->state();
456 DCHECK(!state.Contains(GENERIC));
457 State old_state = state;
458 if (object->IsNull()) {
459 state.Add(NULL_TYPE);
460 } else if (object->IsUndefined()) {
461 state.Add(UNDEFINED);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100462 } else if (object->IsUndetectableObject() || object->IsSmi()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000463 state.RemoveAll();
464 state.Add(GENERIC);
465 } else if (IsMonomorphic()) {
466 state.RemoveAll();
467 state.Add(GENERIC);
468 } else {
469 state.Add(MONOMORPHIC_MAP);
470 }
471 TraceTransition(old_state, state);
472 set_sub_minor_key(TypesBits::update(sub_minor_key(), state.ToIntegral()));
473}
474
475
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000476Handle<Code> TurboFanCodeStub::GenerateCode() {
477 const char* name = CodeStub::MajorName(MajorKey());
478 Zone zone;
479 CallInterfaceDescriptor descriptor(GetCallInterfaceDescriptor());
480 compiler::CodeStubAssembler assembler(isolate(), &zone, descriptor,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100481 GetCodeFlags(), name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482 GenerateAssembly(&assembler);
483 return assembler.GenerateCode();
484}
485
486
487void StringLengthStub::GenerateAssembly(
488 compiler::CodeStubAssembler* assembler) const {
489 compiler::Node* value = assembler->Parameter(0);
490 compiler::Node* string =
491 assembler->LoadObjectField(value, JSValue::kValueOffset);
492 compiler::Node* result =
493 assembler->LoadObjectField(string, String::kLengthOffset);
494 assembler->Return(result);
495}
496
497
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498template<class StateType>
499void HydrogenCodeStub::TraceTransition(StateType from, StateType to) {
500 // Note: Although a no-op transition is semantically OK, it is hinting at a
501 // bug somewhere in our state transition machinery.
502 DCHECK(from != to);
503 if (!FLAG_trace_ic) return;
504 OFStream os(stdout);
505 os << "[";
506 PrintBaseName(os);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400507 os << ": " << from << "=>" << to << "]" << std::endl;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000508}
509
510
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400511void CompareNilICStub::PrintBaseName(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000512 CodeStub::PrintBaseName(os);
513 os << ((nil_value() == kNullValue) ? "(NullValue)" : "(UndefinedValue)");
514}
515
516
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400517void CompareNilICStub::PrintState(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000518 os << state();
519}
520
521
522// TODO(svenpanne) Make this a real infix_ostream_iterator.
523class SimpleListPrinter {
524 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400525 explicit SimpleListPrinter(std::ostream& os) : os_(os), first_(true) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526
527 void Add(const char* s) {
528 if (first_) {
529 first_ = false;
530 } else {
531 os_ << ",";
532 }
533 os_ << s;
Ben Murdoch086aeea2011-05-13 15:57:08 +0100534 }
535
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000536 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400537 std::ostream& os_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000538 bool first_;
539};
540
541
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400542std::ostream& operator<<(std::ostream& os, const CompareNilICStub::State& s) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543 os << "(";
544 SimpleListPrinter p(os);
545 if (s.IsEmpty()) p.Add("None");
546 if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined");
547 if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null");
548 if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap");
549 if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic");
550 return os << ")";
551}
552
553
554Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) {
555 State state = this->state();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100556 if (state.Contains(CompareNilICStub::GENERIC)) return Type::Any();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000557
Ben Murdoch097c5b22016-05-18 11:27:45 +0100558 Type* result = Type::None();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000559 if (state.Contains(CompareNilICStub::UNDEFINED)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100560 result = Type::Union(result, Type::Undefined(), zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000561 }
562 if (state.Contains(CompareNilICStub::NULL_TYPE)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100563 result = Type::Union(result, Type::Null(), zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000564 }
565 if (state.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100566 Type* type = map.is_null() ? Type::Detectable() : Type::Class(map, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000567 result = Type::Union(result, type, zone);
Ben Murdoch086aeea2011-05-13 15:57:08 +0100568 }
569
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570 return result;
571}
Ben Murdoch086aeea2011-05-13 15:57:08 +0100572
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000573
574Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) {
575 Type* output_type = GetType(zone, map);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100576 Type* nil_type = nil_value() == kNullValue ? Type::Null() : Type::Undefined();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000577 return Type::Union(output_type, nil_type, zone);
578}
579
580
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400581void CallICStub::PrintState(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000582 os << state();
583}
584
585
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100586void JSEntryStub::FinishCode(Handle<Code> code) {
587 Handle<FixedArray> handler_table =
588 code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
589 handler_table->set(0, Smi::FromInt(handler_offset_));
590 code->set_handler_table(*handler_table);
591}
592
593
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000594void LoadDictionaryElementStub::InitializeDescriptor(
595 CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 descriptor->Initialize(
597 FUNCTION_ADDR(Runtime_KeyedLoadIC_MissFromStubFailure));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000598}
599
600
601void KeyedLoadGenericStub::InitializeDescriptor(
602 CodeStubDescriptor* descriptor) {
603 descriptor->Initialize(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100604 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000605}
606
607
608void HandlerStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
609 if (kind() == Code::STORE_IC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000610 descriptor->Initialize(FUNCTION_ADDR(Runtime_StoreIC_MissFromStubFailure));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000611 } else if (kind() == Code::KEYED_LOAD_IC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000612 descriptor->Initialize(
613 FUNCTION_ADDR(Runtime_KeyedLoadIC_MissFromStubFailure));
614 } else if (kind() == Code::KEYED_STORE_IC) {
615 descriptor->Initialize(
616 FUNCTION_ADDR(Runtime_KeyedStoreIC_MissFromStubFailure));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617 }
618}
619
620
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000621CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000622 if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623 return LoadWithVectorDescriptor(isolate());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000625 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
626 return VectorStoreICDescriptor(isolate());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000627 }
628}
629
630
631void StoreFastElementStub::InitializeDescriptor(
632 CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633 descriptor->Initialize(
634 FUNCTION_ADDR(Runtime_KeyedStoreIC_MissFromStubFailure));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000635}
636
637
638void ElementsTransitionAndStoreStub::InitializeDescriptor(
639 CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000640 descriptor->Initialize(
641 FUNCTION_ADDR(Runtime_ElementsTransitionAndStoreIC_Miss));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000642}
643
644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645void ToObjectStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
646 descriptor->Initialize(Runtime::FunctionForId(Runtime::kToObject)->entry);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400647}
648
649
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000650CallInterfaceDescriptor StoreTransitionStub::GetCallInterfaceDescriptor()
651 const {
652 return VectorStoreTransitionDescriptor(isolate());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000653}
654
655
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000656CallInterfaceDescriptor
657ElementsTransitionAndStoreStub::GetCallInterfaceDescriptor() const {
658 return VectorStoreTransitionDescriptor(isolate());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000659}
660
661
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000662void FastNewClosureStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663 descriptor->Initialize(Runtime::FunctionForId(Runtime::kNewClosure)->entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000664}
665
666
667void FastNewContextStub::InitializeDescriptor(CodeStubDescriptor* d) {}
668
669
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000670void TypeofStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {}
671
672
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000673void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
674 NumberToStringDescriptor call_descriptor(isolate());
675 descriptor->Initialize(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000676 Runtime::FunctionForId(Runtime::kNumberToString)->entry);
677}
678
679
680void FastCloneRegExpStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
681 FastCloneRegExpDescriptor call_descriptor(isolate());
682 descriptor->Initialize(
683 Runtime::FunctionForId(Runtime::kCreateRegExpLiteral)->entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684}
685
686
687void FastCloneShallowArrayStub::InitializeDescriptor(
688 CodeStubDescriptor* descriptor) {
689 FastCloneShallowArrayDescriptor call_descriptor(isolate());
690 descriptor->Initialize(
691 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry);
692}
693
694
695void FastCloneShallowObjectStub::InitializeDescriptor(
696 CodeStubDescriptor* descriptor) {
697 FastCloneShallowObjectDescriptor call_descriptor(isolate());
698 descriptor->Initialize(
699 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry);
700}
701
702
703void CreateAllocationSiteStub::InitializeDescriptor(CodeStubDescriptor* d) {}
704
705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000706void CreateWeakCellStub::InitializeDescriptor(CodeStubDescriptor* d) {}
707
708
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000709void RegExpConstructResultStub::InitializeDescriptor(
710 CodeStubDescriptor* descriptor) {
711 descriptor->Initialize(
712 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry);
713}
714
715
716void TransitionElementsKindStub::InitializeDescriptor(
717 CodeStubDescriptor* descriptor) {
718 descriptor->Initialize(
719 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry);
720}
721
722
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400723void AllocateHeapNumberStub::InitializeDescriptor(
724 CodeStubDescriptor* descriptor) {
725 descriptor->Initialize(
726 Runtime::FunctionForId(Runtime::kAllocateHeapNumber)->entry);
727}
728
729
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000730void AllocateMutableHeapNumberStub::InitializeDescriptor(
731 CodeStubDescriptor* descriptor) {
732 descriptor->Initialize();
733}
734
735
736void AllocateInNewSpaceStub::InitializeDescriptor(
737 CodeStubDescriptor* descriptor) {
738 descriptor->Initialize();
739}
740
741
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000742void CompareNilICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000743 descriptor->Initialize(FUNCTION_ADDR(Runtime_CompareNilIC_Miss));
744 descriptor->SetMissHandler(ExternalReference(
745 Runtime::FunctionForId(Runtime::kCompareNilIC_Miss), isolate()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000746}
747
748
749void ToBooleanStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000750 descriptor->Initialize(FUNCTION_ADDR(Runtime_ToBooleanIC_Miss));
751 descriptor->SetMissHandler(ExternalReference(
752 Runtime::FunctionForId(Runtime::kToBooleanIC_Miss), isolate()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000753}
754
755
756void BinaryOpICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000757 descriptor->Initialize(FUNCTION_ADDR(Runtime_BinaryOpIC_Miss));
758 descriptor->SetMissHandler(ExternalReference(
759 Runtime::FunctionForId(Runtime::kBinaryOpIC_Miss), isolate()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000760}
761
762
763void BinaryOpWithAllocationSiteStub::InitializeDescriptor(
764 CodeStubDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000765 descriptor->Initialize(
766 FUNCTION_ADDR(Runtime_BinaryOpIC_MissWithAllocationSite));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000767}
768
769
770void StringAddStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
771 descriptor->Initialize(Runtime::FunctionForId(Runtime::kStringAdd)->entry);
772}
773
774
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000775void GrowArrayElementsStub::InitializeDescriptor(
776 CodeStubDescriptor* descriptor) {
777 descriptor->Initialize(
778 Runtime::FunctionForId(Runtime::kGrowArrayElements)->entry);
779}
780
781
782void TypeofStub::GenerateAheadOfTime(Isolate* isolate) {
783 TypeofStub stub(isolate);
784 stub.GetCode();
785}
786
787
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000788void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
789 CreateAllocationSiteStub stub(isolate);
790 stub.GetCode();
791}
792
793
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) {
795 CreateWeakCellStub stub(isolate);
796 stub.GetCode();
797}
798
799
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000800void StoreElementStub::Generate(MacroAssembler* masm) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100801 DCHECK_EQ(DICTIONARY_ELEMENTS, elements_kind());
802 ElementHandlerCompiler::GenerateStoreSlow(masm);
Ben Murdoch257744e2011-11-30 15:57:28 +0000803}
804
805
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806// static
807void StoreFastElementStub::GenerateAheadOfTime(Isolate* isolate) {
808 StoreFastElementStub(isolate, false, FAST_HOLEY_ELEMENTS, STANDARD_STORE)
809 .GetCode();
810 StoreFastElementStub(isolate, false, FAST_HOLEY_ELEMENTS,
811 STORE_AND_GROW_NO_TRANSITION).GetCode();
812 for (int i = FIRST_FAST_ELEMENTS_KIND; i <= LAST_FAST_ELEMENTS_KIND; i++) {
813 ElementsKind kind = static_cast<ElementsKind>(i);
814 StoreFastElementStub(isolate, true, kind, STANDARD_STORE).GetCode();
815 StoreFastElementStub(isolate, true, kind, STORE_AND_GROW_NO_TRANSITION)
816 .GetCode();
817 }
818}
819
820
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400821void ArrayConstructorStub::PrintName(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000822 os << "ArrayConstructorStub";
823 switch (argument_count()) {
824 case ANY:
825 os << "_Any";
826 break;
827 case NONE:
828 os << "_None";
829 break;
830 case ONE:
831 os << "_One";
832 break;
833 case MORE_THAN_ONE:
834 os << "_More_Than_One";
835 break;
836 }
837 return;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000838}
839
840
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400841std::ostream& ArrayConstructorStubBase::BasePrintName(
842 std::ostream& os, // NOLINT
843 const char* name) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000844 os << name << "_" << ElementsKindToString(elements_kind());
845 if (override_mode() == DISABLE_ALLOCATION_SITES) {
846 os << "_DISABLE_ALLOCATION_SITES";
847 }
848 return os;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000849}
850
851
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000852bool ToBooleanStub::UpdateStatus(Handle<Object> object) {
853 Types new_types = types();
854 Types old_types = new_types;
855 bool to_boolean_value = new_types.UpdateStatus(object);
856 TraceTransition(old_types, new_types);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000857 set_sub_minor_key(TypesBits::update(sub_minor_key(), new_types.ToIntegral()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000858 return to_boolean_value;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000859}
860
861
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400862void ToBooleanStub::PrintState(std::ostream& os) const { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000863 os << types();
864}
865
866
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400867std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& s) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868 os << "(";
869 SimpleListPrinter p(os);
870 if (s.IsEmpty()) p.Add("None");
871 if (s.Contains(ToBooleanStub::UNDEFINED)) p.Add("Undefined");
872 if (s.Contains(ToBooleanStub::BOOLEAN)) p.Add("Bool");
873 if (s.Contains(ToBooleanStub::NULL_TYPE)) p.Add("Null");
874 if (s.Contains(ToBooleanStub::SMI)) p.Add("Smi");
875 if (s.Contains(ToBooleanStub::SPEC_OBJECT)) p.Add("SpecObject");
876 if (s.Contains(ToBooleanStub::STRING)) p.Add("String");
877 if (s.Contains(ToBooleanStub::SYMBOL)) p.Add("Symbol");
878 if (s.Contains(ToBooleanStub::HEAP_NUMBER)) p.Add("HeapNumber");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000879 if (s.Contains(ToBooleanStub::SIMD_VALUE)) p.Add("SimdValue");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000880 return os << ")";
881}
882
883
884bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000885 if (object->IsUndefined()) {
886 Add(UNDEFINED);
887 return false;
888 } else if (object->IsBoolean()) {
889 Add(BOOLEAN);
890 return object->IsTrue();
891 } else if (object->IsNull()) {
892 Add(NULL_TYPE);
893 return false;
894 } else if (object->IsSmi()) {
895 Add(SMI);
896 return Smi::cast(*object)->value() != 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000897 } else if (object->IsJSReceiver()) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000898 Add(SPEC_OBJECT);
899 return !object->IsUndetectableObject();
900 } else if (object->IsString()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100901 DCHECK(!object->IsUndetectableObject());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000902 Add(STRING);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100903 return String::cast(*object)->length() != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000904 } else if (object->IsSymbol()) {
905 Add(SYMBOL);
906 return true;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000907 } else if (object->IsHeapNumber()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000908 DCHECK(!object->IsUndetectableObject());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000909 Add(HEAP_NUMBER);
910 double value = HeapNumber::cast(*object)->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000911 return value != 0 && !std::isnan(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000912 } else if (object->IsSimd128Value()) {
913 Add(SIMD_VALUE);
914 return true;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000915 } else {
916 // We should never see an internal object at runtime here!
917 UNREACHABLE();
918 return true;
919 }
920}
921
922
923bool ToBooleanStub::Types::NeedsMap() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 return Contains(ToBooleanStub::SPEC_OBJECT) ||
925 Contains(ToBooleanStub::STRING) || Contains(ToBooleanStub::SYMBOL) ||
926 Contains(ToBooleanStub::HEAP_NUMBER) ||
927 Contains(ToBooleanStub::SIMD_VALUE);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000928}
929
930
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000931void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) {
932 StubFailureTrampolineStub stub1(isolate, NOT_JS_FUNCTION_STUB_MODE);
933 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE);
934 stub1.GetCode();
935 stub2.GetCode();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100936}
937
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000938
939void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
940 intptr_t stack_pointer,
941 Isolate* isolate) {
942 FunctionEntryHook entry_hook = isolate->function_entry_hook();
943 DCHECK(entry_hook != NULL);
944 entry_hook(function, stack_pointer);
945}
946
947
948ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
949 : PlatformCodeStub(isolate) {
950 minor_key_ = ArgumentCountBits::encode(ANY);
951 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
952}
953
954
955ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate,
956 int argument_count)
957 : PlatformCodeStub(isolate) {
958 if (argument_count == 0) {
959 minor_key_ = ArgumentCountBits::encode(NONE);
960 } else if (argument_count == 1) {
961 minor_key_ = ArgumentCountBits::encode(ONE);
962 } else if (argument_count >= 2) {
963 minor_key_ = ArgumentCountBits::encode(MORE_THAN_ONE);
964 } else {
965 UNREACHABLE();
966 }
967 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
968}
969
970
971InternalArrayConstructorStub::InternalArrayConstructorStub(
972 Isolate* isolate) : PlatformCodeStub(isolate) {
973 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
974}
975
976
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000977Representation RepresentationFromType(Type* type) {
978 if (type->Is(Type::UntaggedIntegral())) {
979 return Representation::Integer32();
980 }
981
982 if (type->Is(Type::TaggedSigned())) {
983 return Representation::Smi();
984 }
985
986 if (type->Is(Type::UntaggedPointer())) {
987 return Representation::External();
988 }
989
990 DCHECK(!type->Is(Type::Untagged()));
991 return Representation::Tagged();
992}
993
994} // namespace internal
995} // namespace v8