123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- /*
- * Copyright (C) 2011 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.
- */
- #ifndef ValueRecovery_h
- #define ValueRecovery_h
- #include "DataFormat.h"
- #include "JSCJSValue.h"
- #include "MacroAssembler.h"
- #include "VirtualRegister.h"
- #include <stdio.h>
- #include <wtf/Platform.h>
- namespace JSC {
- // 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,
- UnboxedBooleanInGPR,
- #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,
- DoubleDisplacedInJSStack,
- CellDisplacedInJSStack,
- BooleanDisplacedInJSStack,
- // It's an Arguments object.
- ArgumentsThatWereNotCreated,
- // It's a constant.
- Constant,
- // Don't know how to recover it.
- DontKnow
- };
- class ValueRecovery {
- public:
- ValueRecovery()
- : m_technique(DontKnow)
- {
- }
-
- 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);
- #endif
- ValueRecovery result;
- if (dataFormat == DataFormatInteger)
- result.m_technique = UnboxedInt32InGPR;
- else if (dataFormat == DataFormatBoolean)
- result.m_technique = UnboxedBooleanInGPR;
- 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;
- result.m_technique = InPair;
- result.m_source.pair.tagGPR = tagGPR;
- result.m_source.pair.payloadGPR = payloadGPR;
- return result;
- }
- #endif
- static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr)
- {
- ValueRecovery result;
- result.m_technique = InFPR;
- result.m_source.fpr = fpr;
- return result;
- }
-
- static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat)
- {
- ValueRecovery result;
- switch (dataFormat) {
- case DataFormatInteger:
- result.m_technique = Int32DisplacedInJSStack;
- break;
-
- case DataFormatDouble:
- result.m_technique = DoubleDisplacedInJSStack;
- break;
- case DataFormatCell:
- result.m_technique = CellDisplacedInJSStack;
- break;
-
- case DataFormatBoolean:
- result.m_technique = BooleanDisplacedInJSStack;
- break;
-
- default:
- ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage);
- result.m_technique = DisplacedInJSStack;
- break;
- }
- result.m_source.virtualReg = virtualReg;
- return result;
- }
-
- static ValueRecovery constant(JSValue value)
- {
- ValueRecovery result;
- result.m_technique = Constant;
- result.m_source.constant = JSValue::encode(value);
- return result;
- }
-
- static ValueRecovery argumentsThatWereNotCreated()
- {
- ValueRecovery result;
- result.m_technique = ArgumentsThatWereNotCreated;
- return result;
- }
-
- ValueRecoveryTechnique technique() const { return m_technique; }
-
- bool isConstant() const { return m_technique == Constant; }
-
- bool isInRegisters() const
- {
- switch (m_technique) {
- case InGPR:
- case UnboxedInt32InGPR:
- case UnboxedBooleanInGPR:
- #if USE(JSVALUE32_64)
- case InPair:
- #endif
- case InFPR:
- return true;
- default:
- return false;
- }
- }
-
- 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);
- return m_source.gpr;
- }
-
- #if USE(JSVALUE32_64)
- MacroAssembler::RegisterID tagGPR() const
- {
- ASSERT(m_technique == InPair);
- return m_source.pair.tagGPR;
- }
-
- MacroAssembler::RegisterID payloadGPR() const
- {
- ASSERT(m_technique == InPair);
- return m_source.pair.payloadGPR;
- }
- #endif
-
- MacroAssembler::FPRegisterID fpr() const
- {
- ASSERT(m_technique == InFPR);
- return m_source.fpr;
- }
-
- VirtualRegister virtualRegister() const
- {
- ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack);
- return m_source.virtualReg;
- }
-
- JSValue constant() 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
- 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;
- default:
- out.printf("?%d", technique());
- break;
- }
- }
-
- private:
- ValueRecoveryTechnique m_technique;
- union {
- MacroAssembler::RegisterID gpr;
- MacroAssembler::FPRegisterID fpr;
- #if USE(JSVALUE32_64)
- struct {
- MacroAssembler::RegisterID tagGPR;
- MacroAssembler::RegisterID payloadGPR;
- } pair;
- #endif
- VirtualRegister virtualReg;
- EncodedJSValue constant;
- } m_source;
- };
- } // namespace JSC
- #endif // ValueRecovery_h
|