Promote main thread assertions related to sendWithAsyncReply() to be release assertions
[WebKit-https.git] / Source / JavaScriptCore / b3 / B3Value.cpp
1 /*
2  * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "B3Value.h"
28
29 #if ENABLE(B3_JIT)
30
31 #include "B3ArgumentRegValue.h"
32 #include "B3AtomicValue.h"
33 #include "B3BasicBlockInlines.h"
34 #include "B3BottomProvider.h"
35 #include "B3CCallValue.h"
36 #include "B3FenceValue.h"
37 #include "B3MemoryValue.h"
38 #include "B3OriginDump.h"
39 #include "B3ProcedureInlines.h"
40 #include "B3SlotBaseValue.h"
41 #include "B3StackSlot.h"
42 #include "B3UpsilonValue.h"
43 #include "B3ValueInlines.h"
44 #include "B3ValueKeyInlines.h"
45 #include "B3VariableValue.h"
46 #include "B3WasmBoundsCheckValue.h"
47 #include <wtf/CommaPrinter.h>
48 #include <wtf/ListDump.h>
49 #include <wtf/StringPrintStream.h>
50 #include <wtf/Vector.h>
51
52 namespace JSC { namespace B3 {
53
54 const char* const Value::dumpPrefix = "@";
55 void DeepValueDump::dump(PrintStream& out) const
56 {
57     if (m_value)
58         m_value->deepDump(m_proc, out);
59     else
60         out.print("<null>");
61 }
62
63 Value::~Value()
64 {
65     if (m_numChildren == VarArgs)
66         bitwise_cast<Vector<Value*, 3> *>(childrenAlloc())->Vector<Value*, 3>::~Vector();
67 }
68
69 void Value::replaceWithIdentity(Value* value)
70 {
71     // This is a bit crazy. It does an in-place replacement of whatever Value subclass this is with
72     // a plain Identity Value. We first collect all of the information we need, then we destruct the
73     // previous value in place, and then we construct the Identity Value in place.
74
75     RELEASE_ASSERT(m_type == value->m_type);
76     ASSERT(value != this);
77
78     if (m_type == Void)
79         replaceWithNopIgnoringType();
80     else
81         replaceWith(Identity, m_type, this->owner, value);
82 }
83
84 void Value::replaceWithBottom(InsertionSet& insertionSet, size_t index)
85 {
86     replaceWithBottom(BottomProvider(insertionSet, index));
87 }
88
89 void Value::replaceWithNop()
90 {
91     RELEASE_ASSERT(m_type == Void);
92     replaceWithNopIgnoringType();
93 }
94
95 void Value::replaceWithNopIgnoringType()
96 {
97     replaceWith(Nop, Void, this->owner);
98 }
99
100 void Value::replaceWithPhi()
101 {
102     if (m_type == Void) {
103         replaceWithNop();
104         return;
105     }
106
107     replaceWith(Phi, m_type, this->owner);
108 }
109
110 void Value::replaceWithJump(BasicBlock* owner, FrequentedBlock target)
111 {
112     RELEASE_ASSERT(owner->last() == this);
113     replaceWith(Jump, Void, this->owner);
114     owner->setSuccessors(target);
115 }
116
117 void Value::replaceWithOops(BasicBlock* owner)
118 {
119     RELEASE_ASSERT(owner->last() == this);
120     replaceWith(Oops, Void, this->owner);
121     owner->clearSuccessors();
122 }
123
124 void Value::replaceWithJump(FrequentedBlock target)
125 {
126     replaceWithJump(owner, target);
127 }
128
129 void Value::replaceWithOops()
130 {
131     replaceWithOops(owner);
132 }
133
134 void Value::replaceWith(Kind kind, Type type, BasicBlock* owner)
135 {
136     unsigned index = m_index;
137
138     this->~Value();
139
140     new (this) Value(kind, type, m_origin);
141
142     this->m_index = index;
143     this->owner = owner;
144 }
145
146 void Value::replaceWith(Kind kind, Type type, BasicBlock* owner, Value* value)
147 {
148     unsigned index = m_index;
149
150     this->~Value();
151
152     new (this) Value(kind, type, m_origin, value);
153
154     this->m_index = index;
155     this->owner = owner;
156 }
157
158 void Value::dump(PrintStream& out) const
159 {
160     bool isConstant = false;
161
162     switch (opcode()) {
163     case Const32:
164         out.print("$", asInt32(), "(");
165         isConstant = true;
166         break;
167     case Const64:
168         out.print("$", asInt64(), "(");
169         isConstant = true;
170         break;
171     case ConstFloat:
172         out.print("$", asFloat(), "(");
173         isConstant = true;
174         break;
175     case ConstDouble:
176         out.print("$", asDouble(), "(");
177         isConstant = true;
178         break;
179     default:
180         break;
181     }
182     
183     out.print(dumpPrefix, m_index);
184
185     if (isConstant)
186         out.print(")");
187 }
188
189 void Value::dumpChildren(CommaPrinter& comma, PrintStream& out) const
190 {
191     for (Value* child : children())
192         out.print(comma, pointerDump(child));
193 }
194
195 void Value::deepDump(const Procedure* proc, PrintStream& out) const
196 {
197     out.print(m_type, " ", dumpPrefix, m_index, " = ", m_kind);
198
199     out.print("(");
200     CommaPrinter comma;
201     dumpChildren(comma, out);
202
203     dumpMeta(comma, out);
204
205     {
206         CString string = toCString(effects());
207         if (string.length())
208             out.print(comma, string);
209     }
210
211     if (m_origin)
212         out.print(comma, OriginDump(proc, m_origin));
213
214     out.print(")");
215 }
216
217 void Value::dumpSuccessors(const BasicBlock* block, PrintStream& out) const
218 {
219     // Note that this must not crash if we have the wrong number of successors, since someone
220     // debugging a number-of-successors bug will probably want to dump IR!
221     
222     if (opcode() == Branch && block->numSuccessors() == 2) {
223         out.print("Then:", block->taken(), ", Else:", block->notTaken());
224         return;
225     }
226     
227     out.print(listDump(block->successors()));
228 }
229
230 Value* Value::negConstant(Procedure&) const
231 {
232     return nullptr;
233 }
234
235 Value* Value::addConstant(Procedure&, int32_t) const
236 {
237     return nullptr;
238 }
239
240 Value* Value::addConstant(Procedure&, const Value*) const
241 {
242     return nullptr;
243 }
244
245 Value* Value::subConstant(Procedure&, const Value*) const
246 {
247     return nullptr;
248 }
249
250 Value* Value::mulConstant(Procedure&, const Value*) const
251 {
252     return nullptr;
253 }
254
255 Value* Value::checkAddConstant(Procedure&, const Value*) const
256 {
257     return nullptr;
258 }
259
260 Value* Value::checkSubConstant(Procedure&, const Value*) const
261 {
262     return nullptr;
263 }
264
265 Value* Value::checkMulConstant(Procedure&, const Value*) const
266 {
267     return nullptr;
268 }
269
270 Value* Value::checkNegConstant(Procedure&) const
271 {
272     return nullptr;
273 }
274
275 Value* Value::divConstant(Procedure&, const Value*) const
276 {
277     return nullptr;
278 }
279
280 Value* Value::uDivConstant(Procedure&, const Value*) const
281 {
282     return nullptr;
283 }
284
285 Value* Value::modConstant(Procedure&, const Value*) const
286 {
287     return nullptr;
288 }
289
290 Value* Value::uModConstant(Procedure&, const Value*) const
291 {
292     return nullptr;
293 }
294
295 Value* Value::bitAndConstant(Procedure&, const Value*) const
296 {
297     return nullptr;
298 }
299
300 Value* Value::bitOrConstant(Procedure&, const Value*) const
301 {
302     return nullptr;
303 }
304
305 Value* Value::bitXorConstant(Procedure&, const Value*) const
306 {
307     return nullptr;
308 }
309
310 Value* Value::shlConstant(Procedure&, const Value*) const
311 {
312     return nullptr;
313 }
314
315 Value* Value::sShrConstant(Procedure&, const Value*) const
316 {
317     return nullptr;
318 }
319
320 Value* Value::zShrConstant(Procedure&, const Value*) const
321 {
322     return nullptr;
323 }
324
325 Value* Value::rotRConstant(Procedure&, const Value*) const
326 {
327     return nullptr;
328 }
329
330 Value* Value::rotLConstant(Procedure&, const Value*) const
331 {
332     return nullptr;
333 }
334
335 Value* Value::bitwiseCastConstant(Procedure&) const
336 {
337     return nullptr;
338 }
339
340 Value* Value::iToDConstant(Procedure&) const
341 {
342     return nullptr;
343 }
344
345 Value* Value::iToFConstant(Procedure&) const
346 {
347     return nullptr;
348 }
349
350 Value* Value::doubleToFloatConstant(Procedure&) const
351 {
352     return nullptr;
353 }
354
355 Value* Value::floatToDoubleConstant(Procedure&) const
356 {
357     return nullptr;
358 }
359
360 Value* Value::absConstant(Procedure&) const
361 {
362     return nullptr;
363 }
364
365 Value* Value::ceilConstant(Procedure&) const
366 {
367     return nullptr;
368 }
369
370 Value* Value::floorConstant(Procedure&) const
371 {
372     return nullptr;
373 }
374
375 Value* Value::sqrtConstant(Procedure&) const
376 {
377     return nullptr;
378 }
379
380 TriState Value::equalConstant(const Value*) const
381 {
382     return MixedTriState;
383 }
384
385 TriState Value::notEqualConstant(const Value*) const
386 {
387     return MixedTriState;
388 }
389
390 TriState Value::lessThanConstant(const Value*) const
391 {
392     return MixedTriState;
393 }
394
395 TriState Value::greaterThanConstant(const Value*) const
396 {
397     return MixedTriState;
398 }
399
400 TriState Value::lessEqualConstant(const Value*) const
401 {
402     return MixedTriState;
403 }
404
405 TriState Value::greaterEqualConstant(const Value*) const
406 {
407     return MixedTriState;
408 }
409
410 TriState Value::aboveConstant(const Value*) const
411 {
412     return MixedTriState;
413 }
414
415 TriState Value::belowConstant(const Value*) const
416 {
417     return MixedTriState;
418 }
419
420 TriState Value::aboveEqualConstant(const Value*) const
421 {
422     return MixedTriState;
423 }
424
425 TriState Value::belowEqualConstant(const Value*) const
426 {
427     return MixedTriState;
428 }
429
430 TriState Value::equalOrUnorderedConstant(const Value*) const
431 {
432     return MixedTriState;
433 }
434
435 Value* Value::invertedCompare(Procedure& proc) const
436 {
437     if (numChildren() != 2)
438         return nullptr;
439     if (Optional<Opcode> invertedOpcode = B3::invertedCompare(opcode(), child(0)->type())) {
440         ASSERT(!kind().hasExtraBits());
441         return proc.add<Value>(*invertedOpcode, type(), origin(), child(0), child(1));
442     }
443     return nullptr;
444 }
445
446 bool Value::isRounded() const
447 {
448     ASSERT(type().isFloat());
449     switch (opcode()) {
450     case Floor:
451     case Ceil:
452     case IToD:
453     case IToF:
454         return true;
455
456     case ConstDouble: {
457         double value = asDouble();
458         return std::isfinite(value) && value == ceil(value);
459     }
460
461     case ConstFloat: {
462         float value = asFloat();
463         return std::isfinite(value) && value == ceilf(value);
464     }
465
466     default:
467         return false;
468     }
469 }
470
471 bool Value::returnsBool() const
472 {
473     if (type() != Int32)
474         return false;
475
476     switch (opcode()) {
477     case Const32:
478         return asInt32() == 0 || asInt32() == 1;
479     case BitAnd:
480         return child(0)->returnsBool() || child(1)->returnsBool();
481     case BitOr:
482     case BitXor:
483         return child(0)->returnsBool() && child(1)->returnsBool();
484     case Select:
485         return child(1)->returnsBool() && child(2)->returnsBool();
486     case Identity:
487         return child(0)->returnsBool();
488     case Equal:
489     case NotEqual:
490     case LessThan:
491     case GreaterThan:
492     case LessEqual:
493     case GreaterEqual:
494     case Above:
495     case Below:
496     case AboveEqual:
497     case BelowEqual:
498     case EqualOrUnordered:
499     case AtomicWeakCAS:
500         return true;
501     case Phi:
502         // FIXME: We should have a story here.
503         // https://bugs.webkit.org/show_bug.cgi?id=150725
504         return false;
505     default:
506         return false;
507     }
508 }
509
510 TriState Value::asTriState() const
511 {
512     switch (opcode()) {
513     case Const32:
514         return triState(!!asInt32());
515     case Const64:
516         return triState(!!asInt64());
517     case ConstDouble:
518         // Use "!= 0" to really emphasize what this mean with respect to NaN and such.
519         return triState(asDouble() != 0);
520     case ConstFloat:
521         return triState(asFloat() != 0.);
522     default:
523         return MixedTriState;
524     }
525 }
526
527 Effects Value::effects() const
528 {
529     Effects result;
530     switch (opcode()) {
531     case Nop:
532     case Identity:
533     case Opaque:
534     case Const32:
535     case Const64:
536     case ConstDouble:
537     case ConstFloat:
538     case SlotBase:
539     case ArgumentReg:
540     case FramePointer:
541     case Add:
542     case Sub:
543     case Mul:
544     case Neg:
545     case BitAnd:
546     case BitOr:
547     case BitXor:
548     case Shl:
549     case SShr:
550     case ZShr:
551     case RotR:
552     case RotL:
553     case Clz:
554     case Abs:
555     case Ceil:
556     case Floor:
557     case Sqrt:
558     case BitwiseCast:
559     case SExt8:
560     case SExt16:
561     case SExt32:
562     case ZExt32:
563     case Trunc:
564     case IToD:
565     case IToF:
566     case FloatToDouble:
567     case DoubleToFloat:
568     case Equal:
569     case NotEqual:
570     case LessThan:
571     case GreaterThan:
572     case LessEqual:
573     case GreaterEqual:
574     case Above:
575     case Below:
576     case AboveEqual:
577     case BelowEqual:
578     case EqualOrUnordered:
579     case Select:
580     case Depend:
581     case Extract:
582         break;
583     case Div:
584     case UDiv:
585     case Mod:
586     case UMod:
587         result.controlDependent = true;
588         break;
589     case Load8Z:
590     case Load8S:
591     case Load16Z:
592     case Load16S:
593     case Load: {
594         const MemoryValue* memory = as<MemoryValue>();
595         result.reads = memory->range();
596         if (memory->hasFence()) {
597             result.writes = memory->fenceRange();
598             result.fence = true;
599         }
600         result.controlDependent = true;
601         break;
602     }
603     case Store8:
604     case Store16:
605     case Store: {
606         const MemoryValue* memory = as<MemoryValue>();
607         result.writes = memory->range();
608         if (memory->hasFence()) {
609             result.reads = memory->fenceRange();
610             result.fence = true;
611         }
612         result.controlDependent = true;
613         break;
614     }
615     case AtomicWeakCAS:
616     case AtomicStrongCAS:
617     case AtomicXchgAdd:
618     case AtomicXchgAnd:
619     case AtomicXchgOr:
620     case AtomicXchgSub:
621     case AtomicXchgXor:
622     case AtomicXchg: {
623         const AtomicValue* atomic = as<AtomicValue>();
624         result.reads = atomic->range() | atomic->fenceRange();
625         result.writes = atomic->range() | atomic->fenceRange();
626         if (atomic->hasFence())
627             result.fence = true;
628         result.controlDependent = true;
629         break;
630     }
631     case WasmAddress:
632         result.readsPinned = true;
633         break;
634     case Fence: {
635         const FenceValue* fence = as<FenceValue>();
636         result.reads = fence->read;
637         result.writes = fence->write;
638         result.fence = true;
639         break;
640     }
641     case CCall:
642         result = as<CCallValue>()->effects;
643         break;
644     case Patchpoint:
645         result = as<PatchpointValue>()->effects;
646         break;
647     case CheckAdd:
648     case CheckSub:
649     case CheckMul:
650     case Check:
651         result = Effects::forCheck();
652         break;
653     case WasmBoundsCheck:
654         switch (as<WasmBoundsCheckValue>()->boundsType()) {
655         case WasmBoundsCheckValue::Type::Pinned:
656             result.readsPinned = true;
657             break;
658         case WasmBoundsCheckValue::Type::Maximum:
659             break;
660         }
661         result.exitsSideways = true;
662         break;
663     case Upsilon:
664     case Set:
665         result.writesLocalState = true;
666         break;
667     case Phi:
668     case Get:
669         result.readsLocalState = true;
670         break;
671     case Jump:
672     case Branch:
673     case Switch:
674     case Return:
675     case Oops:
676     case EntrySwitch:
677         result.terminal = true;
678         break;
679     }
680     if (traps()) {
681         result.exitsSideways = true;
682         result.reads = HeapRange::top();
683     }
684     return result;
685 }
686
687 ValueKey Value::key() const
688 {
689     // NOTE: Except for exotic things like CheckAdd and friends, we want every case here to have a
690     // corresponding case in ValueKey::materialize().
691     switch (opcode()) {
692     case FramePointer:
693         return ValueKey(kind(), type());
694     case Identity:
695     case Opaque:
696     case Abs:
697     case Ceil:
698     case Floor:
699     case Sqrt:
700     case SExt8:
701     case SExt16:
702     case SExt32:
703     case ZExt32:
704     case Clz:
705     case Trunc:
706     case IToD:
707     case IToF:
708     case FloatToDouble:
709     case DoubleToFloat:
710     case Check:
711     case BitwiseCast:
712     case Neg:
713     case Depend:
714         return ValueKey(kind(), type(), child(0));
715     case Add:
716     case Sub:
717     case Mul:
718     case Div:
719     case UDiv:
720     case Mod:
721     case UMod:
722     case BitAnd:
723     case BitOr:
724     case BitXor:
725     case Shl:
726     case SShr:
727     case ZShr:
728     case RotR:
729     case RotL:
730     case Equal:
731     case NotEqual:
732     case LessThan:
733     case GreaterThan:
734     case Above:
735     case Below:
736     case AboveEqual:
737     case BelowEqual:
738     case EqualOrUnordered:
739     case CheckAdd:
740     case CheckSub:
741     case CheckMul:
742         return ValueKey(kind(), type(), child(0), child(1));
743     case Select:
744         return ValueKey(kind(), type(), child(0), child(1), child(2));
745     case Const32:
746         return ValueKey(Const32, type(), static_cast<int64_t>(asInt32()));
747     case Const64:
748         return ValueKey(Const64, type(), asInt64());
749     case ConstDouble:
750         return ValueKey(ConstDouble, type(), asDouble());
751     case ConstFloat:
752         return ValueKey(ConstFloat, type(), asFloat());
753     case ArgumentReg:
754         return ValueKey(
755             ArgumentReg, type(),
756             static_cast<int64_t>(as<ArgumentRegValue>()->argumentReg().index()));
757     case SlotBase:
758         return ValueKey(
759             SlotBase, type(),
760             static_cast<int64_t>(as<SlotBaseValue>()->slot()->index()));
761     default:
762         return ValueKey();
763     }
764 }
765
766 Value* Value::foldIdentity() const
767 {
768     Value* current = const_cast<Value*>(this);
769     while (current->opcode() == Identity)
770         current = current->child(0);
771     return current;
772 }
773
774 bool Value::performSubstitution()
775 {
776     bool result = false;
777     for (Value*& child : children()) {
778         if (child->opcode() == Identity) {
779             result = true;
780             child = child->foldIdentity();
781         }
782     }
783     return result;
784 }
785
786 bool Value::isFree() const
787 {
788     switch (opcode()) {
789     case Const32:
790     case Const64:
791     case ConstDouble:
792     case ConstFloat:
793     case Identity:
794     case Opaque:
795     case Nop:
796         return true;
797     default:
798         return false;
799     }
800 }
801
802 void Value::dumpMeta(CommaPrinter&, PrintStream&) const
803 {
804 }
805
806 Type Value::typeFor(Kind kind, Value* firstChild, Value* secondChild)
807 {
808     switch (kind.opcode()) {
809     case Identity:
810     case Opaque:
811     case Add:
812     case Sub:
813     case Mul:
814     case Div:
815     case UDiv:
816     case Mod:
817     case UMod:
818     case Neg:
819     case BitAnd:
820     case BitOr:
821     case BitXor:
822     case Shl:
823     case SShr:
824     case ZShr:
825     case RotR:
826     case RotL:
827     case Clz:
828     case Abs:
829     case Ceil:
830     case Floor:
831     case Sqrt:
832     case CheckAdd:
833     case CheckSub:
834     case CheckMul:
835     case Depend:
836         return firstChild->type();
837     case FramePointer:
838         return pointerType();
839     case SExt8:
840     case SExt16:
841     case Equal:
842     case NotEqual:
843     case LessThan:
844     case GreaterThan:
845     case LessEqual:
846     case GreaterEqual:
847     case Above:
848     case Below:
849     case AboveEqual:
850     case BelowEqual:
851     case EqualOrUnordered:
852         return Int32;
853     case Trunc:
854         return firstChild->type() == Int64 ? Int32 : Float;
855     case SExt32:
856     case ZExt32:
857         return Int64;
858     case FloatToDouble:
859     case IToD:
860         return Double;
861     case DoubleToFloat:
862     case IToF:
863         return Float;
864     case BitwiseCast:
865         switch (firstChild->type().kind()) {
866         case Int64:
867             return Double;
868         case Double:
869             return Int64;
870         case Int32:
871             return Float;
872         case Float:
873             return Int32;
874         case Void:
875         case Tuple:
876             ASSERT_NOT_REACHED();
877         }
878         return Void;
879     case Nop:
880     case Jump:
881     case Branch:
882     case Return:
883     case Oops:
884     case EntrySwitch:
885     case WasmBoundsCheck:
886         return Void;
887     case Select:
888         ASSERT(secondChild);
889         return secondChild->type();
890     default:
891         RELEASE_ASSERT_NOT_REACHED();
892     }
893 }
894
895 void Value::badKind(Kind kind, unsigned numArgs)
896 {
897     dataLog("Bad kind ", kind, " with ", numArgs, " args.\n");
898     RELEASE_ASSERT_NOT_REACHED();
899 }
900
901 } } // namespace JSC::B3
902
903 #endif // ENABLE(B3_JIT)