diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/b3/B3Validate.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/b3/B3Validate.cpp')
-rw-r--r-- | Source/JavaScriptCore/b3/B3Validate.cpp | 479 |
1 files changed, 0 insertions, 479 deletions
diff --git a/Source/JavaScriptCore/b3/B3Validate.cpp b/Source/JavaScriptCore/b3/B3Validate.cpp deleted file mode 100644 index 25f55c6e3..000000000 --- a/Source/JavaScriptCore/b3/B3Validate.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2015-2016 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "B3Validate.h" - -#if ENABLE(B3_JIT) - -#include "B3ArgumentRegValue.h" -#include "B3BasicBlockInlines.h" -#include "B3Dominators.h" -#include "B3MemoryValue.h" -#include "B3Procedure.h" -#include "B3SlotBaseValue.h" -#include "B3StackSlot.h" -#include "B3UpsilonValue.h" -#include "B3ValueInlines.h" -#include "B3Variable.h" -#include "B3VariableValue.h" -#include <wtf/HashSet.h> -#include <wtf/StringPrintStream.h> -#include <wtf/text/CString.h> - -namespace JSC { namespace B3 { - -namespace { - -class Validater { -public: - Validater(Procedure& procedure, const char* dumpBefore) - : m_procedure(procedure) - , m_dumpBefore(dumpBefore) - { - } - -#define VALIDATE(condition, message) do { \ - if (condition) \ - break; \ - fail(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #condition, toCString message); \ - } while (false) - - void run() - { - HashSet<BasicBlock*> blocks; - HashSet<Value*> valueInProc; - HashMap<Value*, unsigned> valueInBlock; - HashMap<Value*, BasicBlock*> valueOwner; - HashMap<Value*, unsigned> valueIndex; - - for (BasicBlock* block : m_procedure) { - blocks.add(block); - for (unsigned i = 0; i < block->size(); ++i) { - Value* value = block->at(i); - valueInBlock.add(value, 0).iterator->value++; - valueOwner.add(value, block); - valueIndex.add(value, i); - } - } - - for (Value* value : m_procedure.values()) - valueInProc.add(value); - - for (Value* value : valueInProc) - VALIDATE(valueInBlock.contains(value), ("At ", *value)); - for (auto& entry : valueInBlock) { - VALIDATE(valueInProc.contains(entry.key), ("At ", *entry.key)); - VALIDATE(entry.value == 1, ("At ", *entry.key)); - } - - // Compute dominators ourselves to avoid perturbing Procedure. - Dominators dominators(m_procedure); - - for (Value* value : valueInProc) { - for (Value* child : value->children()) { - VALIDATE(child, ("At ", *value)); - VALIDATE(valueInProc.contains(child), ("At ", *value, "->", pointerDump(child))); - if (valueOwner.get(child) == valueOwner.get(value)) - VALIDATE(valueIndex.get(value) > valueIndex.get(child), ("At ", *value, "->", pointerDump(child))); - else - VALIDATE(dominators.dominates(valueOwner.get(child), valueOwner.get(value)), ("at ", *value, "->", pointerDump(child))); - } - } - - HashMap<BasicBlock*, HashSet<BasicBlock*>> allPredecessors; - for (BasicBlock* block : blocks) { - VALIDATE(block->size() >= 1, ("At ", *block)); - for (unsigned i = 0; i < block->size() - 1; ++i) - VALIDATE(!ControlValue::accepts(block->at(i)->opcode()), ("At ", *block->at(i))); - VALIDATE(ControlValue::accepts(block->last()->opcode()), ("At ", *block->last())); - - for (BasicBlock* successor : block->successorBlocks()) { - allPredecessors.add(successor, HashSet<BasicBlock*>()).iterator->value.add(block); - VALIDATE( - blocks.contains(successor), ("At ", *block, "->", pointerDump(successor))); - } - } - - // Note that this totally allows dead code. - for (auto& entry : allPredecessors) { - BasicBlock* successor = entry.key; - HashSet<BasicBlock*>& predecessors = entry.value; - VALIDATE(predecessors == successor->predecessors(), ("At ", *successor)); - } - - for (Value* value : m_procedure.values()) { - for (Value* child : value->children()) - VALIDATE(child->type() != Void, ("At ", *value, "->", *child)); - switch (value->opcode()) { - case Nop: - case Jump: - case Oops: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == Void, ("At ", *value)); - break; - case Identity: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); - VALIDATE(value->type() != Void, ("At ", *value)); - break; - case Const32: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - break; - case Const64: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == Int64, ("At ", *value)); - break; - case ConstDouble: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == Double, ("At ", *value)); - break; - case ConstFloat: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == Float, ("At ", *value)); - break; - case Set: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == value->as<VariableValue>()->variable()->type(), ("At ", *value)); - break; - case Get: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == value->as<VariableValue>()->variable()->type(), ("At ", *value)); - break; - case SlotBase: - case FramePointer: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() == pointerType(), ("At ", *value)); - break; - case ArgumentReg: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE( - (value->as<ArgumentRegValue>()->argumentReg().isGPR() ? pointerType() : Double) - == value->type(), ("At ", *value)); - break; - case Add: - case Sub: - case Mul: - case Div: - case Mod: - case BitAnd: - case BitXor: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); - VALIDATE(value->type() == value->child(1)->type(), ("At ", *value)); - VALIDATE(value->type() != Void, ("At ", *value)); - break; - case Neg: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); - VALIDATE(value->type() != Void, ("At ", *value)); - break; - case ChillDiv: - case ChillMod: - case BitOr: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); - VALIDATE(value->type() == value->child(1)->type(), ("At ", *value)); - VALIDATE(isInt(value->type()), ("At ", *value)); - break; - case Shl: - case SShr: - case ZShr: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); - VALIDATE(value->child(1)->type() == Int32, ("At ", *value)); - VALIDATE(isInt(value->type()), ("At ", *value)); - break; - case BitwiseCast: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->type() != value->child(0)->type(), ("At ", *value)); - VALIDATE( - (value->type() == Int64 && value->child(0)->type() == Double) - || (value->type() == Double && value->child(0)->type() == Int64) - || (value->type() == Float && value->child(0)->type() == Int32) - || (value->type() == Int32 && value->child(0)->type() == Float), - ("At ", *value)); - break; - case SExt8: - case SExt16: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == Int32, ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - break; - case SExt32: - case ZExt32: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == Int32, ("At ", *value)); - VALIDATE(value->type() == Int64, ("At ", *value)); - break; - case Clz: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(isInt(value->type()), ("At ", *value)); - break; - case Trunc: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == Int64, ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - break; - case Abs: - case Ceil: - case Floor: - case Sqrt: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(isFloat(value->child(0)->type()), ("At ", *value)); - VALIDATE(isFloat(value->type()), ("At ", *value)); - break; - case IToD: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(value->type() == Double, ("At ", *value)); - break; - case FloatToDouble: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == Float, ("At ", *value)); - VALIDATE(value->type() == Double, ("At ", *value)); - break; - case DoubleToFloat: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == Double, ("At ", *value)); - VALIDATE(value->type() == Float, ("At ", *value)); - break; - case Equal: - case NotEqual: - case LessThan: - case GreaterThan: - case LessEqual: - case GreaterEqual: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - break; - case Above: - case Below: - case AboveEqual: - case BelowEqual: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - break; - case EqualOrUnordered: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value)); - VALIDATE(isFloat(value->child(0)->type()), ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - break; - case Select: - VALIDATE(value->numChildren() == 3, ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(value->type() == value->child(1)->type(), ("At ", *value)); - VALIDATE(value->type() == value->child(2)->type(), ("At ", *value)); - break; - case Load8Z: - case Load8S: - case Load16Z: - case Load16S: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value)); - VALIDATE(value->type() == Int32, ("At ", *value)); - validateStackAccess(value); - break; - case Load: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value)); - VALIDATE(value->type() != Void, ("At ", *value)); - validateStackAccess(value); - break; - case Store8: - case Store16: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->child(0)->type() == Int32, ("At ", *value)); - VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value)); - VALIDATE(value->type() == Void, ("At ", *value)); - validateStackAccess(value); - break; - case Store: - VALIDATE(value->numChildren() == 2, ("At ", *value)); - VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value)); - VALIDATE(value->type() == Void, ("At ", *value)); - validateStackAccess(value); - break; - case CCall: - VALIDATE(value->numChildren() >= 1, ("At ", *value)); - VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value)); - break; - case Patchpoint: - if (value->type() == Void) - VALIDATE(value->as<PatchpointValue>()->resultConstraint == ValueRep::WarmAny, ("At ", *value)); - else { - switch (value->as<PatchpointValue>()->resultConstraint.kind()) { - case ValueRep::WarmAny: - case ValueRep::SomeRegister: - case ValueRep::Register: - case ValueRep::StackArgument: - break; - default: - VALIDATE(false, ("At ", *value)); - break; - } - - validateStackmapConstraint(value, ConstrainedValue(value, value->as<PatchpointValue>()->resultConstraint)); - } - validateStackmap(value); - break; - case CheckAdd: - case CheckSub: - case CheckMul: - VALIDATE(value->numChildren() >= 2, ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(isInt(value->child(1)->type()), ("At ", *value)); - VALIDATE(value->as<StackmapValue>()->constrainedChild(0).rep() == ValueRep::WarmAny, ("At ", *value)); - VALIDATE(value->as<StackmapValue>()->constrainedChild(1).rep() == ValueRep::WarmAny, ("At ", *value)); - validateStackmap(value); - break; - case Check: - VALIDATE(value->numChildren() >= 1, ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(value->as<StackmapValue>()->constrainedChild(0).rep() == ValueRep::WarmAny, ("At ", *value)); - validateStackmap(value); - break; - case Upsilon: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->as<UpsilonValue>()->phi(), ("At ", *value)); - VALIDATE(value->as<UpsilonValue>()->phi()->opcode() == Phi, ("At ", *value)); - VALIDATE(value->child(0)->type() == value->as<UpsilonValue>()->phi()->type(), ("At ", *value)); - VALIDATE(valueInProc.contains(value->as<UpsilonValue>()->phi()), ("At ", *value)); - break; - case Phi: - VALIDATE(!value->numChildren(), ("At ", *value)); - VALIDATE(value->type() != Void, ("At ", *value)); - break; - case Return: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(value->type() == Void, ("At ", *value)); - break; - case Branch: - case Switch: - VALIDATE(value->numChildren() == 1, ("At ", *value)); - VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); - VALIDATE(value->type() == Void, ("At ", *value)); - break; - } - - VALIDATE(!(value->effects().writes && value->key()), ("At ", *value)); - } - - for (Variable* variable : m_procedure.variables()) - VALIDATE(variable->type() != Void, ("At ", *variable)); - } - -private: - void validateStackmap(Value* value) - { - StackmapValue* stackmap = value->as<StackmapValue>(); - VALIDATE(stackmap, ("At ", *value)); - VALIDATE(stackmap->numChildren() >= stackmap->reps().size(), ("At ", *stackmap)); - for (ConstrainedValue child : stackmap->constrainedChildren()) - validateStackmapConstraint(stackmap, child); - } - - void validateStackmapConstraint(Value* context, const ConstrainedValue& value) - { - switch (value.rep().kind()) { - case ValueRep::WarmAny: - case ValueRep::ColdAny: - case ValueRep::LateColdAny: - case ValueRep::SomeRegister: - case ValueRep::StackArgument: - break; - case ValueRep::Register: - if (value.rep().reg().isGPR()) - VALIDATE(isInt(value.value()->type()), ("At ", *context, ": ", value)); - else - VALIDATE(isFloat(value.value()->type()), ("At ", *context, ": ", value)); - break; - default: - VALIDATE(false, ("At ", *context, ": ", value)); - break; - } - } - - void validateStackAccess(Value* value) - { - MemoryValue* memory = value->as<MemoryValue>(); - SlotBaseValue* slotBase = value->lastChild()->as<SlotBaseValue>(); - if (!slotBase) - return; - - StackSlot* stack = slotBase->slot(); - - VALIDATE(memory->offset() >= 0, ("At ", *value)); - VALIDATE(memory->offset() + memory->accessByteSize() <= stack->byteSize(), ("At ", *value)); - } - - NO_RETURN_DUE_TO_CRASH void fail( - const char* filename, int lineNumber, const char* function, const char* condition, - CString message) - { - CString failureMessage; - { - StringPrintStream out; - out.print("B3 VALIDATION FAILURE\n"); - out.print(" ", condition, " (", filename, ":", lineNumber, ")\n"); - out.print(" ", message, "\n"); - out.print(" After ", m_procedure.lastPhaseName(), "\n"); - failureMessage = out.toCString(); - } - - dataLog(failureMessage); - if (m_dumpBefore) { - dataLog("Before ", m_procedure.lastPhaseName(), ":\n"); - dataLog(m_dumpBefore); - } - dataLog("At time of failure:\n"); - dataLog(m_procedure); - - dataLog(failureMessage); - WTFReportAssertionFailure(filename, lineNumber, function, condition); - CRASH(); - } - - Procedure& m_procedure; - const char* m_dumpBefore; -}; - -} // anonymous namespace - -void validate(Procedure& procedure, const char* dumpBefore) -{ - Validater validater(procedure, dumpBefore); - validater.run(); -} - -} } // namespace JSC::B3 - -#endif // ENABLE(B3_JIT) |