Bug 1245112 - Part 11: Move generic MacroAssembler methods into check_macroassembler_style block. r=nbp

This commit is contained in:
Tooru Fujisawa 2016-02-15 23:01:49 +09:00
parent ea4ea88d45
commit 0f7aa8f299
3 changed files with 202 additions and 181 deletions

View File

@ -317,8 +317,8 @@ MacroAssembler::addPtr(ImmPtr imm, Register dest)
addPtr(ImmWord(uintptr_t(imm.value)), dest);
}
//}}} check_macroassembler_style
// ===============================================================
// Branch functions
template <class L>
void
@ -381,46 +381,6 @@ MacroAssembler::branchIfInterpreted(Register fun, Label* label)
branchTest32(Assembler::NonZero, address, Imm32(bit), label);
}
void
MacroAssembler::branchTestNeedsIncrementalBarrier(Condition cond, Label* label)
{
MOZ_ASSERT(cond == Zero || cond == NonZero);
CompileZone* zone = GetJitContext()->compartment->zone();
AbsoluteAddress needsBarrierAddr(zone->addressOfNeedsIncrementalBarrier());
branchTest32(cond, needsBarrierAddr, Imm32(0x1), label);
}
void
MacroAssembler::branchTestObjectTruthy(bool truthy, Register objReg, Register scratch,
Label* slowCheck, Label* checked)
{
// The branches to out-of-line code here implement a conservative version
// of the JSObject::isWrapper test performed in EmulatesUndefined. If none
// of the branches are taken, we can check class flags directly.
loadObjClass(objReg, scratch);
Address flags(scratch, Class::offsetOfFlags());
branchTestClassIsProxy(true, scratch, slowCheck);
Condition cond = truthy ? Assembler::Zero : Assembler::NonZero;
branchTest32(cond, flags, Imm32(JSCLASS_EMULATES_UNDEFINED), checked);
}
void
MacroAssembler::branchTestClassIsProxy(bool proxy, Register clasp, Label* label)
{
branchTest32(proxy ? Assembler::NonZero : Assembler::Zero,
Address(clasp, Class::offsetOfFlags()),
Imm32(JSCLASS_IS_PROXY), label);
}
void
MacroAssembler::branchTestObjectIsProxy(bool proxy, Register object, Register scratch, Label* label)
{
loadObjClass(object, scratch);
branchTestClassIsProxy(proxy, scratch, label);
}
void
MacroAssembler::branchFunctionKind(Condition cond, JSFunction::FunctionKind kind, Register fun,
Register scratch, Label* label)
@ -469,6 +429,37 @@ MacroAssembler::branchTestObjGroup(Condition cond, Register obj, Register group,
branchPtr(cond, Address(obj, JSObject::offsetOfGroup()), group, label);
}
void
MacroAssembler::branchTestObjectTruthy(bool truthy, Register objReg, Register scratch,
Label* slowCheck, Label* checked)
{
// The branches to out-of-line code here implement a conservative version
// of the JSObject::isWrapper test performed in EmulatesUndefined. If none
// of the branches are taken, we can check class flags directly.
loadObjClass(objReg, scratch);
Address flags(scratch, Class::offsetOfFlags());
branchTestClassIsProxy(true, scratch, slowCheck);
Condition cond = truthy ? Assembler::Zero : Assembler::NonZero;
branchTest32(cond, flags, Imm32(JSCLASS_EMULATES_UNDEFINED), checked);
}
void
MacroAssembler::branchTestClassIsProxy(bool proxy, Register clasp, Label* label)
{
branchTest32(proxy ? Assembler::NonZero : Assembler::Zero,
Address(clasp, Class::offsetOfFlags()),
Imm32(JSCLASS_IS_PROXY), label);
}
void
MacroAssembler::branchTestObjectIsProxy(bool proxy, Register object, Register scratch, Label* label)
{
loadObjClass(object, scratch);
branchTestClassIsProxy(proxy, scratch, label);
}
void
MacroAssembler::branchTestProxyHandlerFamily(Condition cond, Register proxy, Register scratch,
const void* handlerp, Label* label)
@ -479,6 +470,49 @@ MacroAssembler::branchTestProxyHandlerFamily(Condition cond, Register proxy, Reg
branchPtr(cond, familyAddr, ImmPtr(handlerp), label);
}
template <typename Value>
void
MacroAssembler::branchTestMIRType(Condition cond, const Value& val, MIRType type, Label* label)
{
switch (type) {
case MIRType_Null: return branchTestNull(cond, val, label);
case MIRType_Undefined: return branchTestUndefined(cond, val, label);
case MIRType_Boolean: return branchTestBoolean(cond, val, label);
case MIRType_Int32: return branchTestInt32(cond, val, label);
case MIRType_String: return branchTestString(cond, val, label);
case MIRType_Symbol: return branchTestSymbol(cond, val, label);
case MIRType_Object: return branchTestObject(cond, val, label);
case MIRType_Double: return branchTestDouble(cond, val, label);
case MIRType_MagicOptimizedArguments: // Fall through.
case MIRType_MagicIsConstructing:
case MIRType_MagicHole: return branchTestMagic(cond, val, label);
default:
MOZ_CRASH("Bad MIRType");
}
}
template <typename T>
void
MacroAssembler::branchKey(Condition cond, const T& length, const Int32Key& key, Label* label)
{
if (key.isRegister())
branch32(cond, length, key.reg(), label);
else
branch32(cond, length, Imm32(key.constant()), label);
}
void
MacroAssembler::branchTestNeedsIncrementalBarrier(Condition cond, Label* label)
{
MOZ_ASSERT(cond == Zero || cond == NonZero);
CompileZone* zone = GetJitContext()->compartment->zone();
AbsoluteAddress needsBarrierAddr(zone->addressOfNeedsIncrementalBarrier());
branchTest32(cond, needsBarrierAddr, Imm32(0x1), label);
}
//}}} check_macroassembler_style
// ===============================================================
#ifndef JS_CODEGEN_ARM64
template <typename T>

View File

@ -2024,57 +2024,6 @@ MacroAssembler::link(JitCode* code)
linkProfilerCallSites(code);
}
void
MacroAssembler::branchIfNotInterpretedConstructor(Register fun, Register scratch, Label* label)
{
// 16-bit loads are slow and unaligned 32-bit loads may be too so
// perform an aligned 32-bit load and adjust the bitmask accordingly.
MOZ_ASSERT(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0);
MOZ_ASSERT(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2);
// First, ensure it's a scripted function.
load32(Address(fun, JSFunction::offsetOfNargs()), scratch);
int32_t bits = IMM32_16ADJ(JSFunction::INTERPRETED);
branchTest32(Assembler::Zero, scratch, Imm32(bits), label);
// Check if the CONSTRUCTOR bit is set.
bits = IMM32_16ADJ(JSFunction::CONSTRUCTOR);
branchTest32(Assembler::Zero, scratch, Imm32(bits), label);
}
void
MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition* maybeDef, Register tag,
Label* label)
{
if (!maybeDef || maybeDef->mightBeType(type)) {
switch (type) {
case MIRType_Null:
branchTestNull(Equal, tag, label);
break;
case MIRType_Boolean:
branchTestBoolean(Equal, tag, label);
break;
case MIRType_Int32:
branchTestInt32(Equal, tag, label);
break;
case MIRType_Double:
branchTestDouble(Equal, tag, label);
break;
case MIRType_String:
branchTestString(Equal, tag, label);
break;
case MIRType_Symbol:
branchTestSymbol(Equal, tag, label);
break;
case MIRType_Object:
branchTestObject(Equal, tag, label);
break;
default:
MOZ_CRASH("Unsupported type");
}
}
}
MacroAssembler::AutoProfilerCallInstrumentation::AutoProfilerCallInstrumentation(
MacroAssembler& masm
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
@ -2536,8 +2485,85 @@ MacroAssembler::linkSelfReference(JitCode* code)
}
}
// ===============================================================
// Branch functions
void
MacroAssembler::branchIfNotInterpretedConstructor(Register fun, Register scratch, Label* label)
{
// 16-bit loads are slow and unaligned 32-bit loads may be too so
// perform an aligned 32-bit load and adjust the bitmask accordingly.
MOZ_ASSERT(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0);
MOZ_ASSERT(JSFunction::offsetOfFlags() == JSFunction::offsetOfNargs() + 2);
// First, ensure it's a scripted function.
load32(Address(fun, JSFunction::offsetOfNargs()), scratch);
int32_t bits = IMM32_16ADJ(JSFunction::INTERPRETED);
branchTest32(Assembler::Zero, scratch, Imm32(bits), label);
// Check if the CONSTRUCTOR bit is set.
bits = IMM32_16ADJ(JSFunction::CONSTRUCTOR);
branchTest32(Assembler::Zero, scratch, Imm32(bits), label);
}
void
MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition* maybeDef, Register tag,
Label* label)
{
if (!maybeDef || maybeDef->mightBeType(type)) {
switch (type) {
case MIRType_Null:
branchTestNull(Equal, tag, label);
break;
case MIRType_Boolean:
branchTestBoolean(Equal, tag, label);
break;
case MIRType_Int32:
branchTestInt32(Equal, tag, label);
break;
case MIRType_Double:
branchTestDouble(Equal, tag, label);
break;
case MIRType_String:
branchTestString(Equal, tag, label);
break;
case MIRType_Symbol:
branchTestSymbol(Equal, tag, label);
break;
case MIRType_Object:
branchTestObject(Equal, tag, label);
break;
default:
MOZ_CRASH("Unsupported type");
}
}
}
//}}} check_macroassembler_style
void
MacroAssembler::BranchType::emit(MacroAssembler& masm)
{
MOZ_ASSERT(isInitialized());
MIRType mirType = MIRType_None;
if (type_.isPrimitive()) {
if (type_.isMagicArguments())
mirType = MIRType_MagicOptimizedArguments;
else
mirType = MIRTypeFromValueType(type_.primitive());
} else if (type_.isAnyObject()) {
mirType = MIRType_Object;
} else {
MOZ_CRASH("Unknown conversion to mirtype");
}
if (mirType == MIRType_Double)
masm.branchTestNumber(cond(), reg(), jump());
else
masm.branchTestMIRType(cond(), reg(), mirType, jump());
}
void
MacroAssembler::BranchGCPtr::emit(MacroAssembler& masm)
{

View File

@ -284,27 +284,7 @@ class MacroAssembler : public MacroAssemblerSpecific
type_(type)
{ }
void emit(MacroAssembler& masm) {
MOZ_ASSERT(isInitialized());
MIRType mirType = MIRType_None;
if (type_.isPrimitive()) {
if (type_.isMagicArguments())
mirType = MIRType_MagicOptimizedArguments;
else
mirType = MIRTypeFromValueType(type_.primitive());
} else if (type_.isAnyObject()) {
mirType = MIRType_Object;
} else {
MOZ_CRASH("Unknown conversion to mirtype");
}
if (mirType == MIRType_Double)
masm.branchTestNumber(cond(), reg(), jump());
else
masm.branchTestMIRType(cond(), reg(), mirType, jump());
}
void emit(MacroAssembler& masm);
};
/*
@ -866,6 +846,55 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTest64(Condition cond, Register64 lhs, Register64 rhs, Register temp,
Label* label) PER_ARCH;
// Branches to |label| if |reg| is false. |reg| should be a C++ bool.
template <class L>
inline void branchIfFalseBool(Register reg, L label);
// Branches to |label| if |reg| is true. |reg| should be a C++ bool.
inline void branchIfTrueBool(Register reg, Label* label);
inline void branchIfRope(Register str, Label* label);
inline void branchLatin1String(Register string, Label* label);
inline void branchTwoByteString(Register string, Label* label);
inline void branchIfFunctionHasNoScript(Register fun, Label* label);
inline void branchIfInterpreted(Register fun, Label* label);
inline void branchFunctionKind(Condition cond, JSFunction::FunctionKind kind, Register fun,
Register scratch, Label* label);
void branchIfNotInterpretedConstructor(Register fun, Register scratch, Label* label);
inline void branchTestObjClass(Condition cond, Register obj, Register scratch, const js::Class* clasp,
Label* label);
inline void branchTestObjShape(Condition cond, Register obj, const Shape* shape, Label* label);
inline void branchTestObjShape(Condition cond, Register obj, Register shape, Label* label);
inline void branchTestObjGroup(Condition cond, Register obj, ObjectGroup* group, Label* label);
inline void branchTestObjGroup(Condition cond, Register obj, Register group, Label* label);
inline void branchTestObjectTruthy(bool truthy, Register objReg, Register scratch,
Label* slowCheck, Label* checked);
inline void branchTestClassIsProxy(bool proxy, Register clasp, Label* label);
inline void branchTestObjectIsProxy(bool proxy, Register object, Register scratch, Label* label);
inline void branchTestProxyHandlerFamily(Condition cond, Register proxy, Register scratch,
const void* handlerp, Label* label);
template <typename Value>
inline void branchTestMIRType(Condition cond, const Value& val, MIRType type, Label* label);
// Emit type case branch on tag matching if the type tag in the definition
// might actually be that type.
void branchEqualTypeIfNeeded(MIRType type, MDefinition* maybeDef, Register tag, Label* label);
template<typename T>
inline void branchKey(Condition cond, const T& length, const Int32Key& key, Label* label);
inline void branchTestNeedsIncrementalBarrier(Condition cond, Label* label);
//}}} check_macroassembler_style
public:
@ -893,40 +922,6 @@ class MacroAssembler : public MacroAssemblerSpecific
loadObjGroup(objReg, dest);
loadPtr(Address(dest, ObjectGroup::offsetOfClasp()), dest);
}
inline void branchTestObjClass(Condition cond, Register obj, Register scratch, const js::Class* clasp,
Label* label);
inline void branchTestObjShape(Condition cond, Register obj, const Shape* shape, Label* label);
inline void branchTestObjShape(Condition cond, Register obj, Register shape, Label* label);
inline void branchTestObjGroup(Condition cond, Register obj, ObjectGroup* group, Label* label);
inline void branchTestObjGroup(Condition cond, Register obj, Register group, Label* label);
inline void branchTestProxyHandlerFamily(Condition cond, Register proxy, Register scratch,
const void* handlerp, Label* label);
template <typename Value>
void branchTestMIRType(Condition cond, const Value& val, MIRType type, Label* label) {
switch (type) {
case MIRType_Null: return branchTestNull(cond, val, label);
case MIRType_Undefined: return branchTestUndefined(cond, val, label);
case MIRType_Boolean: return branchTestBoolean(cond, val, label);
case MIRType_Int32: return branchTestInt32(cond, val, label);
case MIRType_String: return branchTestString(cond, val, label);
case MIRType_Symbol: return branchTestSymbol(cond, val, label);
case MIRType_Object: return branchTestObject(cond, val, label);
case MIRType_Double: return branchTestDouble(cond, val, label);
case MIRType_MagicOptimizedArguments: // Fall through.
case MIRType_MagicIsConstructing:
case MIRType_MagicHole: return branchTestMagic(cond, val, label);
default:
MOZ_CRASH("Bad MIRType");
}
}
// Branches to |label| if |reg| is false. |reg| should be a C++ bool.
template <class L>
inline void branchIfFalseBool(Register reg, L label);
// Branches to |label| if |reg| is true. |reg| should be a C++ bool.
inline void branchIfTrueBool(Register reg, Label* label);
void loadObjPrivate(Register obj, uint32_t nfixed, Register dest) {
loadPtr(Address(obj, NativeObject::getPrivateDataOffset(nfixed)), dest);
@ -944,11 +939,6 @@ class MacroAssembler : public MacroAssemblerSpecific
void loadStringChars(Register str, Register dest);
void loadStringChar(Register str, Register index, Register output);
inline void branchIfRope(Register str, Label* label);
inline void branchLatin1String(Register string, Label* label);
inline void branchTwoByteString(Register string, Label* label);
void loadJSContext(Register dest) {
loadPtr(AbsoluteAddress(GetJitContext()->runtime->addressOfJSContext()), dest);
}
@ -1066,11 +1056,6 @@ class MacroAssembler : public MacroAssemblerSpecific
return extractObject(source, scratch);
}
inline void branchIfFunctionHasNoScript(Register fun, Label* label);
inline void branchIfInterpreted(Register fun, Label* label);
void branchIfNotInterpretedConstructor(Register fun, Register scratch, Label* label);
inline void bumpKey(Int32Key* key, int diff);
void storeKey(const Int32Key& key, const Address& dest) {
@ -1080,16 +1065,6 @@ class MacroAssembler : public MacroAssemblerSpecific
store32(Imm32(key.constant()), dest);
}
template<typename T>
void branchKey(Condition cond, const T& length, const Int32Key& key, Label* label) {
if (key.isRegister())
branch32(cond, length, key.reg(), label);
else
branch32(cond, length, Imm32(key.constant()), label);
}
inline void branchTestNeedsIncrementalBarrier(Condition cond, Label* label);
template <typename T>
void callPreBarrier(const T& address, MIRType type) {
Label done;
@ -1221,10 +1196,6 @@ class MacroAssembler : public MacroAssemblerSpecific
bind(&done);
}
// Emit type case branch on tag matching if the type tag in the definition
// might actually be that type.
void branchEqualTypeIfNeeded(MIRType type, MDefinition* maybeDef, Register tag, Label* label);
// Inline allocation.
private:
void checkAllocatorState(Label* fail);
@ -1267,16 +1238,6 @@ class MacroAssembler : public MacroAssemblerSpecific
// Generates code used to complete a bailout.
void generateBailoutTail(Register scratch, Register bailoutInfo);
inline void branchTestObjectTruthy(bool truthy, Register objReg, Register scratch,
Label* slowCheck, Label* checked);
inline void branchTestClassIsProxy(bool proxy, Register clasp, Label* label);
inline void branchTestObjectIsProxy(bool proxy, Register object, Register scratch, Label* label);
inline void branchFunctionKind(Condition cond, JSFunction::FunctionKind kind, Register fun,
Register scratch, Label* label);
public:
#ifndef JS_CODEGEN_ARM64
// StackPointer manipulation functions.