blob: 1455f0a9a98c2a191edcf871a661d70dbc7db394 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 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/compiler/js-operator.h"
6
7#include <limits>
8
9#include "src/base/lazy-instance.h"
10#include "src/compiler/opcodes.h"
11#include "src/compiler/operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker!
13#include "src/type-feedback-vector-inl.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014
15namespace v8 {
16namespace internal {
17namespace compiler {
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019VectorSlotPair::VectorSlotPair() {}
20
21
22int VectorSlotPair::index() const {
23 return vector_.is_null() ? -1 : vector_->GetIndex(slot_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040024}
25
26
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
28 return lhs.slot() == rhs.slot() &&
29 lhs.vector().location() == rhs.vector().location();
30}
31
32
33bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040034 return !(lhs == rhs);
35}
36
37
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038size_t hash_value(VectorSlotPair const& p) {
39 return base::hash_combine(p.slot(), p.vector().location());
40}
41
42
43ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
44 DCHECK_EQ(IrOpcode::kJSConvertReceiver, op->opcode());
45 return OpParameter<ConvertReceiverMode>(op);
46}
47
48
49ToBooleanHints ToBooleanHintsOf(Operator const* op) {
50 DCHECK_EQ(IrOpcode::kJSToBoolean, op->opcode());
51 return OpParameter<ToBooleanHints>(op);
52}
53
54
55size_t hash_value(TailCallMode mode) {
56 return base::hash_value(static_cast<unsigned>(mode));
57}
58
59
60std::ostream& operator<<(std::ostream& os, TailCallMode mode) {
61 switch (mode) {
62 case TailCallMode::kAllow:
63 return os << "ALLOW_TAIL_CALLS";
64 case TailCallMode::kDisallow:
65 return os << "DISALLOW_TAIL_CALLS";
66 }
67 UNREACHABLE();
68 return os;
69}
70
71
72bool operator==(BinaryOperationParameters const& lhs,
73 BinaryOperationParameters const& rhs) {
74 return lhs.language_mode() == rhs.language_mode() &&
75 lhs.hints() == rhs.hints();
76}
77
78
79bool operator!=(BinaryOperationParameters const& lhs,
80 BinaryOperationParameters const& rhs) {
81 return !(lhs == rhs);
82}
83
84
85size_t hash_value(BinaryOperationParameters const& p) {
86 return base::hash_combine(p.language_mode(), p.hints());
87}
88
89
90std::ostream& operator<<(std::ostream& os, BinaryOperationParameters const& p) {
91 return os << p.language_mode() << ", " << p.hints();
92}
93
94
95BinaryOperationParameters const& BinaryOperationParametersOf(
96 Operator const* op) {
97 DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr ||
98 op->opcode() == IrOpcode::kJSBitwiseXor ||
99 op->opcode() == IrOpcode::kJSBitwiseAnd ||
100 op->opcode() == IrOpcode::kJSShiftLeft ||
101 op->opcode() == IrOpcode::kJSShiftRight ||
102 op->opcode() == IrOpcode::kJSShiftRightLogical ||
103 op->opcode() == IrOpcode::kJSAdd ||
104 op->opcode() == IrOpcode::kJSSubtract ||
105 op->opcode() == IrOpcode::kJSMultiply ||
106 op->opcode() == IrOpcode::kJSDivide ||
107 op->opcode() == IrOpcode::kJSModulus);
108 return OpParameter<BinaryOperationParameters>(op);
109}
110
111
112bool operator==(CallConstructParameters const& lhs,
113 CallConstructParameters const& rhs) {
114 return lhs.arity() == rhs.arity() && lhs.feedback() == rhs.feedback();
115}
116
117
118bool operator!=(CallConstructParameters const& lhs,
119 CallConstructParameters const& rhs) {
120 return !(lhs == rhs);
121}
122
123
124size_t hash_value(CallConstructParameters const& p) {
125 return base::hash_combine(p.arity(), p.feedback());
126}
127
128
129std::ostream& operator<<(std::ostream& os, CallConstructParameters const& p) {
130 return os << p.arity();
131}
132
133
134CallConstructParameters const& CallConstructParametersOf(Operator const* op) {
135 DCHECK_EQ(IrOpcode::kJSCallConstruct, op->opcode());
136 return OpParameter<CallConstructParameters>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400137}
138
139
140std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 os << p.arity() << ", " << p.language_mode() << ", " << p.convert_mode()
142 << ", " << p.tail_call_mode();
143 return os;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400144}
145
146
147const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) {
148 DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode());
149 return OpParameter<CallFunctionParameters>(op);
150}
151
152
153bool operator==(CallRuntimeParameters const& lhs,
154 CallRuntimeParameters const& rhs) {
155 return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
156}
157
158
159bool operator!=(CallRuntimeParameters const& lhs,
160 CallRuntimeParameters const& rhs) {
161 return !(lhs == rhs);
162}
163
164
165size_t hash_value(CallRuntimeParameters const& p) {
166 return base::hash_combine(p.id(), p.arity());
167}
168
169
170std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
171 return os << p.id() << ", " << p.arity();
172}
173
174
175const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
176 DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
177 return OpParameter<CallRuntimeParameters>(op);
178}
179
180
181ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
182 : immutable_(immutable),
183 depth_(static_cast<uint16_t>(depth)),
184 index_(static_cast<uint32_t>(index)) {
185 DCHECK(depth <= std::numeric_limits<uint16_t>::max());
186 DCHECK(index <= std::numeric_limits<uint32_t>::max());
187}
188
189
190bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
191 return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
192 lhs.immutable() == rhs.immutable();
193}
194
195
196bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
197 return !(lhs == rhs);
198}
199
200
201size_t hash_value(ContextAccess const& access) {
202 return base::hash_combine(access.depth(), access.index(), access.immutable());
203}
204
205
206std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
207 return os << access.depth() << ", " << access.index() << ", "
208 << access.immutable();
209}
210
211
212ContextAccess const& ContextAccessOf(Operator const* op) {
213 DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
214 op->opcode() == IrOpcode::kJSStoreContext);
215 return OpParameter<ContextAccess>(op);
216}
217
218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219DynamicAccess::DynamicAccess(const Handle<String>& name, TypeofMode typeof_mode)
220 : name_(name), typeof_mode_(typeof_mode) {}
221
222
223bool operator==(DynamicAccess const& lhs, DynamicAccess const& rhs) {
224 UNIMPLEMENTED();
225 return true;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400226}
227
228
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000229bool operator!=(DynamicAccess const& lhs, DynamicAccess const& rhs) {
230 return !(lhs == rhs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400231}
232
233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234size_t hash_value(DynamicAccess const& access) {
235 UNIMPLEMENTED();
236 return 0;
237}
238
239
240std::ostream& operator<<(std::ostream& os, DynamicAccess const& access) {
241 return os << Brief(*access.name()) << ", " << access.typeof_mode();
242}
243
244
245DynamicAccess const& DynamicAccessOf(Operator const* op) {
246 DCHECK_EQ(IrOpcode::kJSLoadDynamic, op->opcode());
247 return OpParameter<DynamicAccess>(op);
248}
249
250
251bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
252 return lhs.name().location() == rhs.name().location() &&
253 lhs.language_mode() == rhs.language_mode() &&
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400254 lhs.feedback() == rhs.feedback();
255}
256
257
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400259 return !(lhs == rhs);
260}
261
262
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000263size_t hash_value(NamedAccess const& p) {
264 return base::hash_combine(p.name().location(), p.language_mode(),
265 p.feedback());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400266}
267
268
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269std::ostream& operator<<(std::ostream& os, NamedAccess const& p) {
270 return os << Brief(*p.name()) << ", " << p.language_mode();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400271}
272
273
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000274NamedAccess const& NamedAccessOf(const Operator* op) {
275 DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
276 op->opcode() == IrOpcode::kJSStoreNamed);
277 return OpParameter<NamedAccess>(op);
278}
279
280
281std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) {
282 return os << p.language_mode();
283}
284
285
286bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) {
287 return lhs.language_mode() == rhs.language_mode() &&
288 lhs.feedback() == rhs.feedback();
289}
290
291
292bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
293 return !(lhs == rhs);
294}
295
296
297PropertyAccess const& PropertyAccessOf(const Operator* op) {
298 DCHECK(op->opcode() == IrOpcode::kJSLoadProperty ||
299 op->opcode() == IrOpcode::kJSStoreProperty);
300 return OpParameter<PropertyAccess>(op);
301}
302
303
304size_t hash_value(PropertyAccess const& p) {
305 return base::hash_combine(p.language_mode(), p.feedback());
306}
307
308
309bool operator==(LoadGlobalParameters const& lhs,
310 LoadGlobalParameters const& rhs) {
311 return lhs.name().location() == rhs.name().location() &&
312 lhs.feedback() == rhs.feedback() &&
313 lhs.typeof_mode() == rhs.typeof_mode();
314}
315
316
317bool operator!=(LoadGlobalParameters const& lhs,
318 LoadGlobalParameters const& rhs) {
319 return !(lhs == rhs);
320}
321
322
323size_t hash_value(LoadGlobalParameters const& p) {
324 return base::hash_combine(p.name().location(), p.typeof_mode());
325}
326
327
328std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
329 return os << Brief(*p.name()) << ", " << p.typeof_mode();
330}
331
332
333const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) {
334 DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
335 return OpParameter<LoadGlobalParameters>(op);
336}
337
338
339bool operator==(StoreGlobalParameters const& lhs,
340 StoreGlobalParameters const& rhs) {
341 return lhs.language_mode() == rhs.language_mode() &&
342 lhs.name().location() == rhs.name().location() &&
343 lhs.feedback() == rhs.feedback();
344}
345
346
347bool operator!=(StoreGlobalParameters const& lhs,
348 StoreGlobalParameters const& rhs) {
349 return !(lhs == rhs);
350}
351
352
353size_t hash_value(StoreGlobalParameters const& p) {
354 return base::hash_combine(p.language_mode(), p.name().location(),
355 p.feedback());
356}
357
358
359std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) {
360 return os << p.language_mode() << ", " << Brief(*p.name());
361}
362
363
364const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
365 DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
366 return OpParameter<StoreGlobalParameters>(op);
367}
368
369
370bool operator==(CreateArgumentsParameters const& lhs,
371 CreateArgumentsParameters const& rhs) {
372 return lhs.type() == rhs.type() && lhs.start_index() == rhs.start_index();
373}
374
375
376bool operator!=(CreateArgumentsParameters const& lhs,
377 CreateArgumentsParameters const& rhs) {
378 return !(lhs == rhs);
379}
380
381
382size_t hash_value(CreateArgumentsParameters const& p) {
383 return base::hash_combine(p.type(), p.start_index());
384}
385
386
387std::ostream& operator<<(std::ostream& os, CreateArgumentsParameters const& p) {
388 return os << p.type() << ", " << p.start_index();
389}
390
391
392const CreateArgumentsParameters& CreateArgumentsParametersOf(
393 const Operator* op) {
394 DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode());
395 return OpParameter<CreateArgumentsParameters>(op);
396}
397
398
399bool operator==(CreateArrayParameters const& lhs,
400 CreateArrayParameters const& rhs) {
401 return lhs.arity() == rhs.arity() &&
402 lhs.site().location() == rhs.site().location();
403}
404
405
406bool operator!=(CreateArrayParameters const& lhs,
407 CreateArrayParameters const& rhs) {
408 return !(lhs == rhs);
409}
410
411
412size_t hash_value(CreateArrayParameters const& p) {
413 return base::hash_combine(p.arity(), p.site().location());
414}
415
416
417std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
418 os << p.arity();
419 if (!p.site().is_null()) os << ", " << Brief(*p.site());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400420 return os;
421}
422
423
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000424const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
425 DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
426 return OpParameter<CreateArrayParameters>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400427}
428
429
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000430bool operator==(CreateClosureParameters const& lhs,
431 CreateClosureParameters const& rhs) {
432 return lhs.pretenure() == rhs.pretenure() &&
433 lhs.shared_info().location() == rhs.shared_info().location();
434}
435
436
437bool operator!=(CreateClosureParameters const& lhs,
438 CreateClosureParameters const& rhs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400439 return !(lhs == rhs);
440}
441
442
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443size_t hash_value(CreateClosureParameters const& p) {
444 return base::hash_combine(p.pretenure(), p.shared_info().location());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400445}
446
447
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
449 return os << p.pretenure() << ", " << Brief(*p.shared_info());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400450}
451
452
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
454 DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
455 return OpParameter<CreateClosureParameters>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400456}
457
458
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000459bool operator==(CreateLiteralParameters const& lhs,
460 CreateLiteralParameters const& rhs) {
461 return lhs.constant().location() == rhs.constant().location() &&
462 lhs.flags() == rhs.flags() && lhs.index() == rhs.index();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400463}
464
465
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000466bool operator!=(CreateLiteralParameters const& lhs,
467 CreateLiteralParameters const& rhs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400468 return !(lhs == rhs);
469}
470
471
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000472size_t hash_value(CreateLiteralParameters const& p) {
473 return base::hash_combine(p.constant().location(), p.flags(), p.index());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400474}
475
476
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000477std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
478 return os << Brief(*p.constant()) << ", " << p.flags() << ", " << p.index();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400479}
480
481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
483 DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
484 op->opcode() == IrOpcode::kJSCreateLiteralObject ||
485 op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
486 return OpParameter<CreateLiteralParameters>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400487}
488
489
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000490#define CACHED_OP_LIST(V) \
491 V(Equal, Operator::kNoProperties, 2, 1) \
492 V(NotEqual, Operator::kNoProperties, 2, 1) \
493 V(StrictEqual, Operator::kNoThrow, 2, 1) \
494 V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
495 V(ToNumber, Operator::kNoProperties, 1, 1) \
496 V(ToString, Operator::kNoProperties, 1, 1) \
497 V(ToName, Operator::kNoProperties, 1, 1) \
498 V(ToObject, Operator::kNoProperties, 1, 1) \
499 V(Yield, Operator::kNoProperties, 1, 1) \
500 V(Create, Operator::kEliminatable, 2, 1) \
501 V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \
502 V(HasProperty, Operator::kNoProperties, 2, 1) \
503 V(TypeOf, Operator::kEliminatable, 1, 1) \
504 V(InstanceOf, Operator::kNoProperties, 2, 1) \
505 V(ForInDone, Operator::kPure, 2, 1) \
506 V(ForInNext, Operator::kNoProperties, 4, 1) \
507 V(ForInPrepare, Operator::kNoProperties, 1, 3) \
508 V(ForInStep, Operator::kPure, 1, 1) \
509 V(LoadMessage, Operator::kNoThrow, 0, 1) \
510 V(StoreMessage, Operator::kNoThrow, 1, 0) \
511 V(StackCheck, Operator::kNoProperties, 0, 0) \
512 V(CreateWithContext, Operator::kNoProperties, 2, 1) \
513 V(CreateModuleContext, Operator::kNoProperties, 2, 1)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400514
515
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000516#define CACHED_OP_LIST_WITH_LANGUAGE_MODE(V) \
517 V(LessThan, Operator::kNoProperties, 2, 1) \
518 V(GreaterThan, Operator::kNoProperties, 2, 1) \
519 V(LessThanOrEqual, Operator::kNoProperties, 2, 1) \
520 V(GreaterThanOrEqual, Operator::kNoProperties, 2, 1)
521
522
523struct JSOperatorGlobalCache final {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400524#define CACHED(Name, properties, value_input_count, value_output_count) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525 struct Name##Operator final : public Operator { \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400526 Name##Operator() \
527 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \
528 value_input_count, Operator::ZeroIfPure(properties), \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000529 Operator::ZeroIfEliminatable(properties), \
530 value_output_count, Operator::ZeroIfPure(properties), \
531 Operator::ZeroIfNoThrow(properties)) {} \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400532 }; \
533 Name##Operator k##Name##Operator;
534 CACHED_OP_LIST(CACHED)
535#undef CACHED
536
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000537
538#define CACHED_WITH_LANGUAGE_MODE(Name, properties, value_input_count, \
539 value_output_count) \
540 template <LanguageMode kLanguageMode> \
541 struct Name##Operator final : public Operator1<LanguageMode> { \
542 Name##Operator() \
543 : Operator1<LanguageMode>( \
544 IrOpcode::kJS##Name, properties, "JS" #Name, value_input_count, \
545 Operator::ZeroIfPure(properties), \
546 Operator::ZeroIfEliminatable(properties), value_output_count, \
547 Operator::ZeroIfPure(properties), \
548 Operator::ZeroIfNoThrow(properties), kLanguageMode) {} \
549 }; \
550 Name##Operator<SLOPPY> k##Name##SloppyOperator; \
551 Name##Operator<STRICT> k##Name##StrictOperator; \
552 Name##Operator<STRONG> k##Name##StrongOperator;
553 CACHED_OP_LIST_WITH_LANGUAGE_MODE(CACHED_WITH_LANGUAGE_MODE)
554#undef CACHED_WITH_LANGUAGE_MODE
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400555};
556
557
558static base::LazyInstance<JSOperatorGlobalCache>::type kCache =
559 LAZY_INSTANCE_INITIALIZER;
560
561
562JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
563 : cache_(kCache.Get()), zone_(zone) {}
564
565
566#define CACHED(Name, properties, value_input_count, value_output_count) \
567 const Operator* JSOperatorBuilder::Name() { \
568 return &cache_.k##Name##Operator; \
569 }
570CACHED_OP_LIST(CACHED)
571#undef CACHED
572
573
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000574#define CACHED_WITH_LANGUAGE_MODE(Name, properties, value_input_count, \
575 value_output_count) \
576 const Operator* JSOperatorBuilder::Name(LanguageMode language_mode) { \
577 switch (language_mode) { \
578 case SLOPPY: \
579 return &cache_.k##Name##SloppyOperator; \
580 case STRICT: \
581 return &cache_.k##Name##StrictOperator; \
582 case STRONG: \
583 return &cache_.k##Name##StrongOperator; \
584 default: \
585 break; /* %*!%^$#@ */ \
586 } \
587 UNREACHABLE(); \
588 return nullptr; \
589 }
590CACHED_OP_LIST_WITH_LANGUAGE_MODE(CACHED_WITH_LANGUAGE_MODE)
591#undef CACHED_WITH_LANGUAGE_MODE
592
593
594const Operator* JSOperatorBuilder::BitwiseOr(LanguageMode language_mode,
595 BinaryOperationHints hints) {
596 // TODO(turbofan): Cache most important versions of this operator.
597 BinaryOperationParameters parameters(language_mode, hints);
598 return new (zone()) Operator1<BinaryOperationParameters>( //--
599 IrOpcode::kJSBitwiseOr, Operator::kNoProperties, // opcode
600 "JSBitwiseOr", // name
601 2, 1, 1, 1, 1, 2, // inputs/outputs
602 parameters); // parameter
603}
604
605
606const Operator* JSOperatorBuilder::BitwiseXor(LanguageMode language_mode,
607 BinaryOperationHints hints) {
608 // TODO(turbofan): Cache most important versions of this operator.
609 BinaryOperationParameters parameters(language_mode, hints);
610 return new (zone()) Operator1<BinaryOperationParameters>( //--
611 IrOpcode::kJSBitwiseXor, Operator::kNoProperties, // opcode
612 "JSBitwiseXor", // name
613 2, 1, 1, 1, 1, 2, // inputs/outputs
614 parameters); // parameter
615}
616
617
618const Operator* JSOperatorBuilder::BitwiseAnd(LanguageMode language_mode,
619 BinaryOperationHints hints) {
620 // TODO(turbofan): Cache most important versions of this operator.
621 BinaryOperationParameters parameters(language_mode, hints);
622 return new (zone()) Operator1<BinaryOperationParameters>( //--
623 IrOpcode::kJSBitwiseAnd, Operator::kNoProperties, // opcode
624 "JSBitwiseAnd", // name
625 2, 1, 1, 1, 1, 2, // inputs/outputs
626 parameters); // parameter
627}
628
629
630const Operator* JSOperatorBuilder::ShiftLeft(LanguageMode language_mode,
631 BinaryOperationHints hints) {
632 // TODO(turbofan): Cache most important versions of this operator.
633 BinaryOperationParameters parameters(language_mode, hints);
634 return new (zone()) Operator1<BinaryOperationParameters>( //--
635 IrOpcode::kJSShiftLeft, Operator::kNoProperties, // opcode
636 "JSShiftLeft", // name
637 2, 1, 1, 1, 1, 2, // inputs/outputs
638 parameters); // parameter
639}
640
641
642const Operator* JSOperatorBuilder::ShiftRight(LanguageMode language_mode,
643 BinaryOperationHints hints) {
644 // TODO(turbofan): Cache most important versions of this operator.
645 BinaryOperationParameters parameters(language_mode, hints);
646 return new (zone()) Operator1<BinaryOperationParameters>( //--
647 IrOpcode::kJSShiftRight, Operator::kNoProperties, // opcode
648 "JSShiftRight", // name
649 2, 1, 1, 1, 1, 2, // inputs/outputs
650 parameters); // parameter
651}
652
653
654const Operator* JSOperatorBuilder::ShiftRightLogical(
655 LanguageMode language_mode, BinaryOperationHints hints) {
656 // TODO(turbofan): Cache most important versions of this operator.
657 BinaryOperationParameters parameters(language_mode, hints);
658 return new (zone()) Operator1<BinaryOperationParameters>( //--
659 IrOpcode::kJSShiftRightLogical, Operator::kNoProperties, // opcode
660 "JSShiftRightLogical", // name
661 2, 1, 1, 1, 1, 2, // inputs/outputs
662 parameters); // parameter
663}
664
665
666const Operator* JSOperatorBuilder::Add(LanguageMode language_mode,
667 BinaryOperationHints hints) {
668 // TODO(turbofan): Cache most important versions of this operator.
669 BinaryOperationParameters parameters(language_mode, hints);
670 return new (zone()) Operator1<BinaryOperationParameters>( //--
671 IrOpcode::kJSAdd, Operator::kNoProperties, // opcode
672 "JSAdd", // name
673 2, 1, 1, 1, 1, 2, // inputs/outputs
674 parameters); // parameter
675}
676
677
678const Operator* JSOperatorBuilder::Subtract(LanguageMode language_mode,
679 BinaryOperationHints hints) {
680 // TODO(turbofan): Cache most important versions of this operator.
681 BinaryOperationParameters parameters(language_mode, hints);
682 return new (zone()) Operator1<BinaryOperationParameters>( //--
683 IrOpcode::kJSSubtract, Operator::kNoProperties, // opcode
684 "JSSubtract", // name
685 2, 1, 1, 1, 1, 2, // inputs/outputs
686 parameters); // parameter
687}
688
689
690const Operator* JSOperatorBuilder::Multiply(LanguageMode language_mode,
691 BinaryOperationHints hints) {
692 // TODO(turbofan): Cache most important versions of this operator.
693 BinaryOperationParameters parameters(language_mode, hints);
694 return new (zone()) Operator1<BinaryOperationParameters>( //--
695 IrOpcode::kJSMultiply, Operator::kNoProperties, // opcode
696 "JSMultiply", // name
697 2, 1, 1, 1, 1, 2, // inputs/outputs
698 parameters); // parameter
699}
700
701
702const Operator* JSOperatorBuilder::Divide(LanguageMode language_mode,
703 BinaryOperationHints hints) {
704 // TODO(turbofan): Cache most important versions of this operator.
705 BinaryOperationParameters parameters(language_mode, hints);
706 return new (zone()) Operator1<BinaryOperationParameters>( //--
707 IrOpcode::kJSDivide, Operator::kNoProperties, // opcode
708 "JSDivide", // name
709 2, 1, 1, 1, 1, 2, // inputs/outputs
710 parameters); // parameter
711}
712
713
714const Operator* JSOperatorBuilder::Modulus(LanguageMode language_mode,
715 BinaryOperationHints hints) {
716 // TODO(turbofan): Cache most important versions of this operator.
717 BinaryOperationParameters parameters(language_mode, hints);
718 return new (zone()) Operator1<BinaryOperationParameters>( //--
719 IrOpcode::kJSModulus, Operator::kNoProperties, // opcode
720 "JSModulus", // name
721 2, 1, 1, 1, 1, 2, // inputs/outputs
722 parameters); // parameter
723}
724
725
726const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
727 // TODO(turbofan): Cache most important versions of this operator.
728 return new (zone()) Operator1<ToBooleanHints>( //--
729 IrOpcode::kJSToBoolean, Operator::kEliminatable, // opcode
730 "JSToBoolean", // name
731 1, 1, 0, 1, 1, 0, // inputs/outputs
732 hints); // parameter
733}
734
735
736const Operator* JSOperatorBuilder::CallFunction(
737 size_t arity, LanguageMode language_mode, VectorSlotPair const& feedback,
738 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) {
739 CallFunctionParameters parameters(arity, language_mode, feedback,
740 tail_call_mode, convert_mode);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400741 return new (zone()) Operator1<CallFunctionParameters>( // --
742 IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode
743 "JSCallFunction", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000744 parameters.arity(), 1, 1, 1, 1, 2, // inputs/outputs
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400745 parameters); // parameter
746}
747
748
749const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
750 size_t arity) {
751 CallRuntimeParameters parameters(id, arity);
752 const Runtime::Function* f = Runtime::FunctionForId(parameters.id());
753 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
754 return new (zone()) Operator1<CallRuntimeParameters>( // --
755 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode
756 "JSCallRuntime", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000757 parameters.arity(), 1, 1, f->result_size, 1, 2, // inputs/outputs
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400758 parameters); // parameter
759}
760
761
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000762const Operator* JSOperatorBuilder::CallConstruct(
763 size_t arity, VectorSlotPair const& feedback) {
764 CallConstructParameters parameters(arity, feedback);
765 return new (zone()) Operator1<CallConstructParameters>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400766 IrOpcode::kJSCallConstruct, Operator::kNoProperties, // opcode
767 "JSCallConstruct", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000768 parameters.arity(), 1, 1, 1, 1, 2, // counts
769 parameters); // parameter
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400770}
771
772
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000773const Operator* JSOperatorBuilder::ConvertReceiver(
774 ConvertReceiverMode convert_mode) {
775 return new (zone()) Operator1<ConvertReceiverMode>( // --
776 IrOpcode::kJSConvertReceiver, Operator::kNoThrow, // opcode
777 "JSConvertReceiver", // name
778 1, 1, 1, 1, 1, 0, // counts
779 convert_mode); // parameter
780}
781
782
783const Operator* JSOperatorBuilder::LoadNamed(LanguageMode language_mode,
784 Handle<Name> name,
785 const VectorSlotPair& feedback) {
786 NamedAccess access(language_mode, name, feedback);
787 return new (zone()) Operator1<NamedAccess>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400788 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
789 "JSLoadNamed", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790 2, 1, 1, 1, 1, 2, // counts
791 access); // parameter
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400792}
793
794
795const Operator* JSOperatorBuilder::LoadProperty(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796 LanguageMode language_mode, VectorSlotPair const& feedback) {
797 PropertyAccess access(language_mode, feedback);
798 return new (zone()) Operator1<PropertyAccess>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400799 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
800 "JSLoadProperty", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000801 3, 1, 1, 1, 1, 2, // counts
802 access); // parameter
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400803}
804
805
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
807 Handle<Name> name,
808 VectorSlotPair const& feedback) {
809 NamedAccess access(language_mode, name, feedback);
810 return new (zone()) Operator1<NamedAccess>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400811 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode
812 "JSStoreNamed", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000813 3, 1, 1, 0, 1, 2, // counts
814 access); // parameter
815}
816
817
818const Operator* JSOperatorBuilder::StoreProperty(
819 LanguageMode language_mode, VectorSlotPair const& feedback) {
820 PropertyAccess access(language_mode, feedback);
821 return new (zone()) Operator1<PropertyAccess>( // --
822 IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode
823 "JSStoreProperty", // name
824 4, 1, 1, 0, 1, 2, // counts
825 access); // parameter
826}
827
828
829const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
830 return new (zone()) Operator1<LanguageMode>( // --
831 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode
832 "JSDeleteProperty", // name
833 2, 1, 1, 1, 1, 2, // counts
834 language_mode); // parameter
835}
836
837
838const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
839 const VectorSlotPair& feedback,
840 TypeofMode typeof_mode) {
841 LoadGlobalParameters parameters(name, feedback, typeof_mode);
842 return new (zone()) Operator1<LoadGlobalParameters>( // --
843 IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode
844 "JSLoadGlobal", // name
845 1, 1, 1, 1, 1, 2, // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400846 parameters); // parameter
847}
848
849
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000850const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
851 const Handle<Name>& name,
852 const VectorSlotPair& feedback) {
853 StoreGlobalParameters parameters(language_mode, feedback, name);
854 return new (zone()) Operator1<StoreGlobalParameters>( // --
855 IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode
856 "JSStoreGlobal", // name
857 2, 1, 1, 0, 1, 2, // counts
858 parameters); // parameter
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400859}
860
861
862const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
863 bool immutable) {
864 ContextAccess access(depth, index, immutable);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 return new (zone()) Operator1<ContextAccess>( // --
866 IrOpcode::kJSLoadContext, // opcode
867 Operator::kNoWrite | Operator::kNoThrow, // flags
868 "JSLoadContext", // name
869 1, 1, 0, 1, 1, 0, // counts
870 access); // parameter
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400871}
872
873
874const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
875 ContextAccess access(depth, index, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000876 return new (zone()) Operator1<ContextAccess>( // --
877 IrOpcode::kJSStoreContext, // opcode
878 Operator::kNoRead | Operator::kNoThrow, // flags
879 "JSStoreContext", // name
880 2, 1, 1, 0, 1, 0, // counts
881 access); // parameter
882}
883
884
885const Operator* JSOperatorBuilder::LoadDynamic(const Handle<String>& name,
886 TypeofMode typeof_mode) {
887 DynamicAccess access(name, typeof_mode);
888 return new (zone()) Operator1<DynamicAccess>( // --
889 IrOpcode::kJSLoadDynamic, Operator::kNoProperties, // opcode
890 "JSLoadDynamic", // name
891 2, 1, 1, 1, 1, 2, // counts
892 access); // parameter
893}
894
895
896const Operator* JSOperatorBuilder::CreateArguments(
897 CreateArgumentsParameters::Type type, int start_index) {
898 DCHECK_IMPLIES(start_index, type == CreateArgumentsParameters::kRestArray);
899 CreateArgumentsParameters parameters(type, start_index);
900 return new (zone()) Operator1<CreateArgumentsParameters>( // --
901 IrOpcode::kJSCreateArguments, Operator::kNoThrow, // opcode
902 "JSCreateArguments", // name
903 1, 1, 1, 1, 1, 0, // counts
904 parameters); // parameter
905}
906
907
908const Operator* JSOperatorBuilder::CreateArray(size_t arity,
909 Handle<AllocationSite> site) {
910 // constructor, new_target, arg1, ..., argN
911 int const value_input_count = static_cast<int>(arity) + 2;
912 CreateArrayParameters parameters(arity, site);
913 return new (zone()) Operator1<CreateArrayParameters>( // --
914 IrOpcode::kJSCreateArray, Operator::kNoProperties, // opcode
915 "JSCreateArray", // name
916 value_input_count, 1, 1, 1, 1, 2, // counts
917 parameters); // parameter
918}
919
920
921const Operator* JSOperatorBuilder::CreateClosure(
922 Handle<SharedFunctionInfo> shared_info, PretenureFlag pretenure) {
923 CreateClosureParameters parameters(shared_info, pretenure);
924 return new (zone()) Operator1<CreateClosureParameters>( // --
925 IrOpcode::kJSCreateClosure, Operator::kNoThrow, // opcode
926 "JSCreateClosure", // name
927 0, 1, 1, 1, 1, 0, // counts
928 parameters); // parameter
929}
930
931
932const Operator* JSOperatorBuilder::CreateLiteralArray(
933 Handle<FixedArray> constant_elements, int literal_flags,
934 int literal_index) {
935 CreateLiteralParameters parameters(constant_elements, literal_flags,
936 literal_index);
937 return new (zone()) Operator1<CreateLiteralParameters>( // --
938 IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties, // opcode
939 "JSCreateLiteralArray", // name
940 1, 1, 1, 1, 1, 2, // counts
941 parameters); // parameter
942}
943
944
945const Operator* JSOperatorBuilder::CreateLiteralObject(
946 Handle<FixedArray> constant_properties, int literal_flags,
947 int literal_index) {
948 CreateLiteralParameters parameters(constant_properties, literal_flags,
949 literal_index);
950 return new (zone()) Operator1<CreateLiteralParameters>( // --
951 IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties, // opcode
952 "JSCreateLiteralObject", // name
953 1, 1, 1, 1, 1, 2, // counts
954 parameters); // parameter
955}
956
957
958const Operator* JSOperatorBuilder::CreateLiteralRegExp(
959 Handle<String> constant_pattern, int literal_flags, int literal_index) {
960 CreateLiteralParameters parameters(constant_pattern, literal_flags,
961 literal_index);
962 return new (zone()) Operator1<CreateLiteralParameters>( // --
963 IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties, // opcode
964 "JSCreateLiteralRegExp", // name
965 1, 1, 1, 1, 1, 2, // counts
966 parameters); // parameter
967}
968
969
970const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count) {
971 return new (zone()) Operator1<int>( // --
972 IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties, // opcode
973 "JSCreateFunctionContext", // name
974 1, 1, 1, 1, 1, 2, // counts
975 slot_count); // parameter
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400976}
977
978
979const Operator* JSOperatorBuilder::CreateCatchContext(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000980 const Handle<String>& name) {
981 return new (zone()) Operator1<Handle<String>>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400982 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode
983 "JSCreateCatchContext", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984 2, 1, 1, 1, 1, 2, // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400985 name); // parameter
986}
987
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000988
989const Operator* JSOperatorBuilder::CreateBlockContext(
990 const Handle<ScopeInfo>& scpope_info) {
991 return new (zone()) Operator1<Handle<ScopeInfo>>( // --
992 IrOpcode::kJSCreateBlockContext, Operator::kNoProperties, // opcode
993 "JSCreateBlockContext", // name
994 1, 1, 1, 1, 1, 2, // counts
995 scpope_info); // parameter
996}
997
998
999const Operator* JSOperatorBuilder::CreateScriptContext(
1000 const Handle<ScopeInfo>& scpope_info) {
1001 return new (zone()) Operator1<Handle<ScopeInfo>>( // --
1002 IrOpcode::kJSCreateScriptContext, Operator::kNoProperties, // opcode
1003 "JSCreateScriptContext", // name
1004 1, 1, 1, 1, 1, 2, // counts
1005 scpope_info); // parameter
1006}
1007
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001008} // namespace compiler
1009} // namespace internal
1010} // namespace v8