1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "jit/KnownClass.h" 8 9 #include "jit/MIR.h" 10 #include "vm/ArrayObject.h" 11 #include "vm/Iteration.h" 12 #include "vm/JSFunction.h" 13 #include "vm/PlainObject.h" // js::PlainObject 14 #include "vm/RegExpObject.h" 15 16 using namespace js; 17 using namespace js::jit; 18 GetObjectKnownClass(const MDefinition * def)19KnownClass jit::GetObjectKnownClass(const MDefinition* def) { 20 MOZ_ASSERT(def->type() == MIRType::Object); 21 22 switch (def->op()) { 23 case MDefinition::Opcode::NewArray: 24 case MDefinition::Opcode::NewArrayDynamicLength: 25 case MDefinition::Opcode::NewArrayObject: 26 case MDefinition::Opcode::Rest: 27 return KnownClass::Array; 28 29 case MDefinition::Opcode::NewObject: 30 case MDefinition::Opcode::NewPlainObject: 31 case MDefinition::Opcode::CreateThis: 32 return KnownClass::PlainObject; 33 34 case MDefinition::Opcode::Lambda: 35 case MDefinition::Opcode::LambdaArrow: 36 case MDefinition::Opcode::FunctionWithProto: 37 return KnownClass::Function; 38 39 case MDefinition::Opcode::RegExp: 40 return KnownClass::RegExp; 41 42 case MDefinition::Opcode::NewIterator: 43 switch (def->toNewIterator()->type()) { 44 case MNewIterator::ArrayIterator: 45 return KnownClass::ArrayIterator; 46 case MNewIterator::StringIterator: 47 return KnownClass::StringIterator; 48 case MNewIterator::RegExpStringIterator: 49 return KnownClass::RegExpStringIterator; 50 } 51 MOZ_CRASH("unreachable"); 52 53 case MDefinition::Opcode::Phi: { 54 if (def->numOperands() == 0) { 55 return KnownClass::None; 56 } 57 58 MDefinition* op = def->getOperand(0); 59 // Check for Phis to avoid recursion for now. 60 if (op->isPhi()) { 61 return KnownClass::None; 62 } 63 64 KnownClass known = GetObjectKnownClass(op); 65 if (known == KnownClass::None) { 66 return KnownClass::None; 67 } 68 69 for (size_t i = 1; i < def->numOperands(); i++) { 70 op = def->getOperand(i); 71 if (op->isPhi() || GetObjectKnownClass(op) != known) { 72 return KnownClass::None; 73 } 74 } 75 76 return known; 77 } 78 79 default: 80 break; 81 } 82 83 return KnownClass::None; 84 } 85 GetObjectKnownJSClass(const MDefinition * def)86const JSClass* jit::GetObjectKnownJSClass(const MDefinition* def) { 87 switch (GetObjectKnownClass(def)) { 88 case KnownClass::PlainObject: 89 return &PlainObject::class_; 90 case KnownClass::Array: 91 return &ArrayObject::class_; 92 case KnownClass::Function: 93 return &FunctionClass; 94 case KnownClass::RegExp: 95 return &RegExpObject::class_; 96 case KnownClass::ArrayIterator: 97 return &ArrayIteratorObject::class_; 98 case KnownClass::StringIterator: 99 return &StringIteratorObject::class_; 100 case KnownClass::RegExpStringIterator: 101 return &RegExpStringIteratorObject::class_; 102 case KnownClass::None: 103 break; 104 } 105 106 return nullptr; 107 } 108