/*
* Copyright (C) 2009 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 CodeLocation_h
#define CodeLocation_h
#include "MacroAssemblerCodeRef.h"
#if ENABLE(ASSEMBLER)
namespace JSC {
class CodeLocationInstruction;
class CodeLocationLabel;
class CodeLocationJump;
class CodeLocationCall;
class CodeLocationNearCall;
class CodeLocationDataLabel32;
class CodeLocationDataLabelPtr;
// The CodeLocation* types are all pretty much do-nothing wrappers around
// CodePtr (or MacroAssemblerCodePtr, to give it its full name). These
// classes only exist to provide type-safety when linking and patching code.
//
// The one new piece of functionallity introduced by these classes is the
// ability to create (or put another way, to re-discover) another CodeLocation
// at an offset from one you already know. When patching code to optimize it
// we often want to patch a number of instructions that are short, fixed
// offsets apart. To reduce memory overhead we will only retain a pointer to
// one of the instructions, and we will use the *AtOffset methods provided by
// CodeLocationCommon to find the other points in the code to modify.
class CodeLocationCommon : public MacroAssemblerCodePtr {
public:
CodeLocationInstruction instructionAtOffset(int offset);
CodeLocationLabel labelAtOffset(int offset);
CodeLocationJump jumpAtOffset(int offset);
CodeLocationCall callAtOffset(int offset);
CodeLocationNearCall nearCallAtOffset(int offset);
CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
protected:
CodeLocationCommon()
{
}
CodeLocationCommon(MacroAssemblerCodePtr location)
: MacroAssemblerCodePtr(location)
{
}
};
class CodeLocationInstruction : public CodeLocationCommon {
public:
CodeLocationInstruction() {}
explicit CodeLocationInstruction(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationInstruction(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
class CodeLocationLabel : public CodeLocationCommon {
public:
CodeLocationLabel() {}
explicit CodeLocationLabel(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationLabel(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
class CodeLocationJump : public CodeLocationCommon {
public:
CodeLocationJump() {}
explicit CodeLocationJump(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationJump(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
class CodeLocationCall : public CodeLocationCommon {
public:
CodeLocationCall() {}
explicit CodeLocationCall(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationCall(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
class CodeLocationNearCall : public CodeLocationCommon {
public:
CodeLocationNearCall() {}
explicit CodeLocationNearCall(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationNearCall(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
class CodeLocationDataLabel32 : public CodeLocationCommon {
public:
CodeLocationDataLabel32() {}
explicit CodeLocationDataLabel32(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationDataLabel32(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
class CodeLocationDataLabelPtr : public CodeLocationCommon {
public:
CodeLocationDataLabelPtr() {}
explicit CodeLocationDataLabelPtr(MacroAssemblerCodePtr location)
: CodeLocationCommon(location) {}
explicit CodeLocationDataLabelPtr(void* location)
: CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
};
inline CodeLocationInstruction CodeLocationCommon::instructionAtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset);
}
inline CodeLocationLabel CodeLocationCommon::labelAtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset);
}
inline CodeLocationJump CodeLocationCommon::jumpAtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset);
}
inline CodeLocationCall CodeLocationCommon::callAtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset);
}
inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset);
}
inline CodeLocationDataLabelPtr CodeLocationCommon::dataLabelPtrAtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset);
}
inline CodeLocationDataLabel32 CodeLocationCommon::dataLabel32AtOffset(int offset)
{
ASSERT_VALID_CODE_OFFSET(offset);
return CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset);
}
} // namespace JSC
#endif // ENABLE(ASSEMBLER)
#endif // CodeLocation_h