/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#define ValueRecovery_h
#include "DataFormat.h"
+#if ENABLE(JIT)
+#include "GPRInfo.h"
+#include "FPRInfo.h"
+#endif
#include "JSCJSValue.h"
#include "MacroAssembler.h"
#include "VirtualRegister.h"
-#include <stdio.h>
-#include <wtf/Platform.h>
namespace JSC {
+struct DumpContext;
+
// Describes how to recover a given bytecode virtual register at a given
// code point.
enum ValueRecoveryTechnique {
- // It's already in the stack at the right location.
- AlreadyInJSStack,
- // It's already in the stack but unboxed.
- AlreadyInJSStackAsUnboxedInt32,
- AlreadyInJSStackAsUnboxedCell,
- AlreadyInJSStackAsUnboxedBoolean,
- AlreadyInJSStackAsUnboxedDouble,
// It's in a register.
InGPR,
UnboxedInt32InGPR,
+ UnboxedInt52InGPR,
+ UnboxedStrictInt52InGPR,
UnboxedBooleanInGPR,
+ UnboxedCellInGPR,
#if USE(JSVALUE32_64)
InPair,
#endif
InFPR,
- UInt32InGPR,
// It's in the stack, but at a different location.
DisplacedInJSStack,
// It's in the stack, at a different location, and it's unboxed.
Int32DisplacedInJSStack,
+ Int52DisplacedInJSStack,
+ StrictInt52DisplacedInJSStack,
DoubleDisplacedInJSStack,
CellDisplacedInJSStack,
BooleanDisplacedInJSStack,
bool isSet() const { return m_technique != DontKnow; }
bool operator!() const { return !isSet(); }
- static ValueRecovery alreadyInJSStack()
- {
- ValueRecovery result;
- result.m_technique = AlreadyInJSStack;
- return result;
- }
-
- static ValueRecovery alreadyInJSStackAsUnboxedInt32()
- {
- ValueRecovery result;
- result.m_technique = AlreadyInJSStackAsUnboxedInt32;
- return result;
- }
-
- static ValueRecovery alreadyInJSStackAsUnboxedCell()
- {
- ValueRecovery result;
- result.m_technique = AlreadyInJSStackAsUnboxedCell;
- return result;
- }
-
- static ValueRecovery alreadyInJSStackAsUnboxedBoolean()
- {
- ValueRecovery result;
- result.m_technique = AlreadyInJSStackAsUnboxedBoolean;
- return result;
- }
-
- static ValueRecovery alreadyInJSStackAsUnboxedDouble()
- {
- ValueRecovery result;
- result.m_technique = AlreadyInJSStackAsUnboxedDouble;
- return result;
- }
-
static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
{
ASSERT(dataFormat != DataFormatNone);
#if USE(JSVALUE32_64)
- ASSERT(dataFormat == DataFormatInteger || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
+ ASSERT(dataFormat == DataFormatInt32 || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
#endif
ValueRecovery result;
- if (dataFormat == DataFormatInteger)
+ if (dataFormat == DataFormatInt32)
result.m_technique = UnboxedInt32InGPR;
+ else if (dataFormat == DataFormatInt52)
+ result.m_technique = UnboxedInt52InGPR;
+ else if (dataFormat == DataFormatStrictInt52)
+ result.m_technique = UnboxedStrictInt52InGPR;
else if (dataFormat == DataFormatBoolean)
result.m_technique = UnboxedBooleanInGPR;
+ else if (dataFormat == DataFormatCell)
+ result.m_technique = UnboxedCellInGPR;
else
result.m_technique = InGPR;
result.m_source.gpr = gpr;
return result;
}
- static ValueRecovery uint32InGPR(MacroAssembler::RegisterID gpr)
- {
- ValueRecovery result;
- result.m_technique = UInt32InGPR;
- result.m_source.gpr = gpr;
- return result;
- }
-
#if USE(JSVALUE32_64)
static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
{
{
ValueRecovery result;
switch (dataFormat) {
- case DataFormatInteger:
+ case DataFormatInt32:
result.m_technique = Int32DisplacedInJSStack;
break;
+ case DataFormatInt52:
+ result.m_technique = Int52DisplacedInJSStack;
+ break;
+
+ case DataFormatStrictInt52:
+ result.m_technique = StrictInt52DisplacedInJSStack;
+ break;
+
case DataFormatDouble:
result.m_technique = DoubleDisplacedInJSStack;
break;
result.m_technique = DisplacedInJSStack;
break;
}
- result.m_source.virtualReg = virtualReg;
+ result.m_source.virtualReg = virtualReg.offset();
return result;
}
case InGPR:
case UnboxedInt32InGPR:
case UnboxedBooleanInGPR:
+ case UnboxedCellInGPR:
+ case UnboxedInt52InGPR:
+ case UnboxedStrictInt52InGPR:
#if USE(JSVALUE32_64)
case InPair:
#endif
}
}
- bool isAlreadyInJSStack() const
- {
- switch (technique()) {
- case AlreadyInJSStack:
- case AlreadyInJSStackAsUnboxedInt32:
- case AlreadyInJSStackAsUnboxedCell:
- case AlreadyInJSStackAsUnboxedBoolean:
- case AlreadyInJSStackAsUnboxedDouble:
- return true;
- default:
- return false;
- }
- }
-
MacroAssembler::RegisterID gpr() const
{
- ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR);
+ ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR);
return m_source.gpr;
}
VirtualRegister virtualRegister() const
{
- ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack);
- return m_source.virtualReg;
+ ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack || m_technique == Int52DisplacedInJSStack || m_technique == StrictInt52DisplacedInJSStack);
+ return VirtualRegister(m_source.virtualReg);
}
- JSValue constant() const
+ ValueRecovery withLocalsOffset(int offset) const
{
- ASSERT(m_technique == Constant);
- return JSValue::decode(m_source.constant);
- }
-
- void dump(PrintStream& out) const
- {
- switch (technique()) {
- case AlreadyInJSStack:
- out.printf("-");
- break;
- case AlreadyInJSStackAsUnboxedInt32:
- out.printf("(int32)");
- break;
- case AlreadyInJSStackAsUnboxedCell:
- out.printf("(cell)");
- break;
- case AlreadyInJSStackAsUnboxedBoolean:
- out.printf("(bool)");
- break;
- case AlreadyInJSStackAsUnboxedDouble:
- out.printf("(double)");
- break;
- case InGPR:
- out.printf("%%r%d", gpr());
- break;
- case UnboxedInt32InGPR:
- out.printf("int32(%%r%d)", gpr());
- break;
- case UnboxedBooleanInGPR:
- out.printf("bool(%%r%d)", gpr());
- break;
- case UInt32InGPR:
- out.printf("uint32(%%r%d)", gpr());
- break;
- case InFPR:
- out.printf("%%fr%d", fpr());
- break;
-#if USE(JSVALUE32_64)
- case InPair:
- out.printf("pair(%%r%d, %%r%d)", tagGPR(), payloadGPR());
- break;
-#endif
+ switch (m_technique) {
case DisplacedInJSStack:
- out.printf("*%d", virtualRegister());
- break;
case Int32DisplacedInJSStack:
- out.printf("*int32(%d)", virtualRegister());
- break;
case DoubleDisplacedInJSStack:
- out.printf("*double(%d)", virtualRegister());
- break;
case CellDisplacedInJSStack:
- out.printf("*cell(%d)", virtualRegister());
- break;
case BooleanDisplacedInJSStack:
- out.printf("*bool(%d)", virtualRegister());
- break;
- case ArgumentsThatWereNotCreated:
- out.printf("arguments");
- break;
- case Constant:
- out.print("[", constant(), "]");
- break;
- case DontKnow:
- out.printf("!");
- break;
+ case Int52DisplacedInJSStack:
+ case StrictInt52DisplacedInJSStack: {
+ ValueRecovery result;
+ result.m_technique = m_technique;
+ result.m_source.virtualReg = m_source.virtualReg + offset;
+ return result;
+ }
+
default:
- out.printf("?%d", technique());
- break;
+ return *this;
}
}
+ JSValue constant() const
+ {
+ ASSERT(m_technique == Constant);
+ return JSValue::decode(m_source.constant);
+ }
+
+ JSValue recover(ExecState*) const;
+
+#if ENABLE(JIT)
+ void dumpInContext(PrintStream& out, DumpContext* context) const;
+ void dump(PrintStream& out) const;
+#endif
+
private:
ValueRecoveryTechnique m_technique;
union {
MacroAssembler::RegisterID payloadGPR;
} pair;
#endif
- VirtualRegister virtualReg;
+ int virtualReg;
EncodedJSValue constant;
} m_source;
};