PowerPC specific sub-directories.

Technically, this is https://codereview.chromium.org/571173003/ from Andrew Low <andrew_low@ca.ibm.com>.

TBR=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/714093002

Cr-Commit-Position: refs/heads/master@{#25255}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25255 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0df953c9
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#if V8_TARGET_ARCH_PPC
#include "src/ic/access-compiler.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
Handle<Code> code) {
__ Jump(code, RelocInfo::CODE_TARGET);
}
Register* PropertyAccessCompiler::load_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
static Register registers[] = {receiver, name, r6, r3, r7, r8};
return registers;
}
Register* PropertyAccessCompiler::store_calling_convention() {
// receiver, name, scratch1, scratch2, scratch3.
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
DCHECK(r6.is(ElementTransitionAndStoreDescriptor::MapRegister()));
static Register registers[] = {receiver, name, r6, r7, r8};
return registers;
}
#undef __
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_PPC
This diff is collapsed.
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#if V8_TARGET_ARCH_PPC
#include "src/ic/ic.h"
#include "src/ic/ic-compiler.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
__ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
StoreDescriptor::ValueRegister());
__ mov(r0, Operand(Smi::FromInt(strict_mode)));
__ Push(r0);
// Do tail-call to runtime routine.
__ TailCallRuntime(Runtime::kSetProperty, 4, 1);
}
#undef __
#define __ ACCESS_MASM(masm())
Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
CodeHandleList* handlers,
Handle<Name> name,
Code::StubType type,
IcCheckType check) {
Label miss;
if (check == PROPERTY &&
(kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
// In case we are compiling an IC for dictionary loads and stores, just
// check whether the name is unique.
if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
Register tmp = scratch1();
__ JumpIfSmi(this->name(), &miss);
__ LoadP(tmp, FieldMemOperand(this->name(), HeapObject::kMapOffset));
__ lbz(tmp, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
__ JumpIfNotUniqueNameInstanceType(tmp, &miss);
} else {
__ Cmpi(this->name(), Operand(name), r0);
__ bne(&miss);
}
}
Label number_case;
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
// Polymorphic keyed stores may use the map register
Register map_reg = scratch1();
DCHECK(kind() != Code::KEYED_STORE_IC ||
map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister()));
int receiver_count = types->length();
int number_of_handled_maps = 0;
__ LoadP(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
for (int current = 0; current < receiver_count; ++current) {
Handle<HeapType> type = types->at(current);
Handle<Map> map = IC::TypeToMap(*type, isolate());
if (!map->is_deprecated()) {
number_of_handled_maps++;
__ mov(ip, Operand(map));
__ cmp(map_reg, ip);
if (type->Is(HeapType::Number())) {
DCHECK(!number_case.is_unused());
__ bind(&number_case);
}
__ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
}
}
DCHECK(number_of_handled_maps != 0);
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
// Return the generated code.
InlineCacheState state =
number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
return GetCode(kind(), type, name, state);
}
Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
MapHandleList* transitioned_maps) {
Label miss;
__ JumpIfSmi(receiver(), &miss);
int receiver_count = receiver_maps->length();
__ LoadP(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
for (int i = 0; i < receiver_count; ++i) {
__ mov(ip, Operand(receiver_maps->at(i)));
__ cmp(scratch1(), ip);
if (transitioned_maps->at(i).is_null()) {
__ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
} else {
Label next_map;
__ bne(&next_map);
__ mov(transition_map(), Operand(transitioned_maps->at(i)));
__ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
__ bind(&next_map);
}
}
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
// Return the generated code.
return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
}
#undef __
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_PPC
This diff is collapsed.
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#if V8_TARGET_ARCH_PPC
#include "src/codegen.h"
#include "src/ic/stub-cache.h"
namespace v8 {
namespace internal {
#define __ ACCESS_MASM(masm)
static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
Code::Flags flags, bool leave_frame,
StubCache::Table table, Register receiver, Register name,
// Number of the cache entry, not scaled.
Register offset, Register scratch, Register scratch2,
Register offset_scratch) {
ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
uintptr_t key_off_addr = reinterpret_cast<uintptr_t>(key_offset.address());
uintptr_t value_off_addr =
reinterpret_cast<uintptr_t>(value_offset.address());
uintptr_t map_off_addr = reinterpret_cast<uintptr_t>(map_offset.address());
// Check the relative positions of the address fields.
DCHECK(value_off_addr > key_off_addr);
DCHECK((value_off_addr - key_off_addr) % 4 == 0);
DCHECK((value_off_addr - key_off_addr) < (256 * 4));
DCHECK(map_off_addr > key_off_addr);
DCHECK((map_off_addr - key_off_addr) % 4 == 0);
DCHECK((map_off_addr - key_off_addr) < (256 * 4));
Label miss;
Register base_addr = scratch;
scratch = no_reg;
// Multiply by 3 because there are 3 fields per entry (name, code, map).
__ ShiftLeftImm(offset_scratch, offset, Operand(1));
__ add(offset_scratch, offset, offset_scratch);
// Calculate the base address of the entry.
__ mov(base_addr, Operand(key_offset));
__ ShiftLeftImm(scratch2, offset_scratch, Operand(kPointerSizeLog2));
__ add(base_addr, base_addr, scratch2);
// Check that the key in the entry matches the name.
__ LoadP(ip, MemOperand(base_addr, 0));
__ cmp(name, ip);
__ bne(&miss);
// Check the map matches.
__ LoadP(ip, MemOperand(base_addr, map_off_addr - key_off_addr));
__ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
__ cmp(ip, scratch2);
__ bne(&miss);
// Get the code entry from the cache.
Register code = scratch2;
scratch2 = no_reg;
__ LoadP(code, MemOperand(base_addr, value_off_addr - key_off_addr));
// Check that the flags match what we're looking for.
Register flags_reg = base_addr;
base_addr = no_reg;
__ lwz(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
DCHECK(!r0.is(flags_reg));
__ li(r0, Operand(Code::kFlagsNotUsedInLookup));
__ andc(flags_reg, flags_reg, r0);
__ mov(r0, Operand(flags));
__ cmpl(flags_reg, r0);
__ bne(&miss);
#ifdef DEBUG
if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
__ b(&miss);
} else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
__ b(&miss);
}
#endif
if (leave_frame) __ LeaveFrame(StackFrame::INTERNAL);
// Jump to the first instruction in the code stub.
__ addi(r0, code, Operand(Code::kHeaderSize - kHeapObjectTag));
__ mtctr(r0);
__ bctr();
// Miss: fall through.
__ bind(&miss);
}
void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
bool leave_frame, Register receiver,
Register name, Register scratch, Register extra,
Register extra2, Register extra3) {
Isolate* isolate = masm->isolate();
Label miss;
#if V8_TARGET_ARCH_PPC64
// Make sure that code is valid. The multiplying code relies on the
// entry size being 24.
DCHECK(sizeof(Entry) == 24);
#else
// Make sure that code is valid. The multiplying code relies on the
// entry size being 12.
DCHECK(sizeof(Entry) == 12);
#endif
// Make sure the flags does not name a specific type.
DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
// Make sure that there are no register conflicts.
DCHECK(!scratch.is(receiver));
DCHECK(!scratch.is(name));
DCHECK(!extra.is(receiver));
DCHECK(!extra.is(name));
DCHECK(!extra.is(scratch));
DCHECK(!extra2.is(receiver));
DCHECK(!extra2.is(name));
DCHECK(!extra2.is(scratch));
DCHECK(!extra2.is(extra));
// Check scratch, extra and extra2 registers are valid.
DCHECK(!scratch.is(no_reg));
DCHECK(!extra.is(no_reg));
DCHECK(!extra2.is(no_reg));
DCHECK(!extra3.is(no_reg));
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
extra3);
// Check that the receiver isn't a smi.
__ JumpIfSmi(receiver, &miss);
// Get the map of the receiver and compute the hash.
__ lwz(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
__ LoadP(ip, FieldMemOperand(receiver, HeapObject::kMapOffset));
__ add(scratch, scratch, ip);
#if V8_TARGET_ARCH_PPC64
// Use only the low 32 bits of the map pointer.
__ rldicl(scratch, scratch, 0, 32);
#endif
uint32_t mask = kPrimaryTableSize - 1;
// We shift out the last two bits because they are not part of the hash and
// they are always 01 for maps.
__ ShiftRightImm(scratch, scratch, Operand(kCacheIndexShift));
// Mask down the eor argument to the minimum to keep the immediate
// encodable.
__ xori(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask));
// Prefer and_ to ubfx here because ubfx takes 2 cycles.
__ andi(scratch, scratch, Operand(mask));
// Probe the primary table.
ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
scratch, extra, extra2, extra3);
// Primary miss: Compute hash for secondary probe.
__ ShiftRightImm(extra, name, Operand(kCacheIndexShift));
__ sub(scratch, scratch, extra);
uint32_t mask2 = kSecondaryTableSize - 1;
__ addi(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2));
__ andi(scratch, scratch, Operand(mask2));
// Probe the secondary table.
ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
scratch, extra, extra2, extra3);
// Cache miss: Fall-through and let caller handle the miss by
// entering the runtime system.
__ bind(&miss);
__ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2,
extra3);
}
#undef __
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_PPC
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_PPC_CODEGEN_PPC_H_
#define V8_PPC_CODEGEN_PPC_H_
#include "src/ast.h"
#include "src/macro-assembler.h"
namespace v8 {
namespace internal {
enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
// indexed character into |result|. We expect |index| as untagged input and
// |result| as untagged output.
static void Generate(MacroAssembler* masm, Register string, Register index,
Register result, Label* call_runtime);
private:
DISALLOW_COPY_AND_ASSIGN(StringCharLoadGenerator);
};
class MathExpGenerator : public AllStatic {
public:
// Register input isn't modified. All other registers are clobbered.
static void EmitMathExp(MacroAssembler* masm, DoubleRegister input,
DoubleRegister result, DoubleRegister double_scratch1,
DoubleRegister double_scratch2, Register temp1,
Register temp2, Register temp3);
private:
DISALLOW_COPY_AND_ASSIGN(MathExpGenerator);
};
}
} // namespace v8::internal
#endif // V8_PPC_CODEGEN_PPC_H_
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#if V8_TARGET_ARCH_PPC
#include "src/ppc/constants-ppc.h"
namespace v8 {
namespace internal {
// These register names are defined in a way to match the native disassembler
// formatting. See for example the command "objdump -d <binary file>".
const char* Registers::names_[kNumRegisters] = {
"r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
"r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "fp"};
// List of alias names which can be used when referring to PPC registers.
const Registers::RegisterAlias Registers::aliases_[] = {{10, "sl"},
{11, "r11"},
{12, "r12"},
{13, "r13"},
{14, "r14"},
{15, "r15"},
{kNoRegister, NULL}};
const char* Registers::Name(int reg) {
const char* result;
if ((0 <= reg) && (reg < kNumRegisters)) {
result = names_[reg];
} else {
result = "noreg";
}
return result;
}
const char* FPRegisters::names_[kNumFPRegisters] = {
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10",
"d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
"d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
const char* FPRegisters::Name(int reg) {
DCHECK((0 <= reg) && (reg < kNumFPRegisters));
return names_[reg];
}
int FPRegisters::Number(const char* name) {
for (int i = 0; i < kNumFPRegisters; i++) {
if (strcmp(names_[i], name) == 0) {
return i;
}
}
// No register with the requested name found.
return kNoRegister;
}
int Registers::Number(const char* name) {
// Look through the canonical names.
for (int i = 0; i < kNumRegisters; i++) {
if (strcmp(names_[i], name) == 0) {
return i;
}
}
// Look through the alias names.
int i = 0;
while (aliases_[i].reg != kNoRegister) {
if (strcmp(aliases_[i].name, name) == 0) {
return aliases_[i].reg;
}
i++;
}
// No register with the requested name found.
return kNoRegister;
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_PPC
This diff is collapsed.
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// CPU specific code for ppc independent of OS goes here.
#include "src/v8.h"
#if V8_TARGET_ARCH_PPC
#include "src/assembler.h"
#include "src/macro-assembler.h"
#include "src/simulator.h" // for cache flushing.
namespace v8 {
namespace internal {
void CpuFeatures::FlushICache(void* buffer, size_t size) {
// Nothing to do flushing no instructions.
if (size == 0) {
return;
}
#if defined(USE_SIMULATOR)
// Not generating PPC instructions for C-code. This means that we are
// building an PPC emulator based target. We should notify the simulator
// that the Icache was flushed.
// None of this code ends up in the snapshot so there are no issues
// around whether or not to generate the code when building snapshots.
Simulator::FlushICache(Isolate::Current()->simulator_i_cache(), buffer, size);
#else
if (CpuFeatures::IsSupported(INSTR_AND_DATA_CACHE_COHERENCY)) {
__asm__ __volatile__(
"sync \n"
"icbi 0, %0 \n"
"isync \n"
: /* no output */
: "r"(buffer)
: "memory");
return;
}
const int kCacheLineSize = CpuFeatures::cache_line_size();
intptr_t mask = kCacheLineSize - 1;
byte *start =
reinterpret_cast<byte *>(reinterpret_cast<intptr_t>(buffer) & ~mask);
byte *end = static_cast<byte *>(buffer) + size;
for (byte *pointer = start; pointer < end; pointer += kCacheLineSize) {
__asm__(
"dcbf 0, %0 \n"
"sync \n"
"icbi 0, %0 \n"
"isync \n"
: /* no output */
: "r"(pointer));
}
#endif // USE_SIMULATOR
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_PPC
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#if V8_TARGET_ARCH_PPC
#include "src/assembler.h"
#include "src/frames.h"
#include "src/macro-assembler.h"
#include "src/ppc/assembler-ppc.h"
#include "src/ppc/assembler-ppc-inl.h"
#include "src/ppc/macro-assembler-ppc.h"
namespace v8 {
namespace internal {
Register JavaScriptFrame::fp_register() { return v8::internal::fp; }
Register JavaScriptFrame::context_register() { return cp; }
Register JavaScriptFrame::constant_pool_pointer_register() {
#if V8_OOL_CONSTANT_POOL
DCHECK(FLAG_enable_ool_constant_pool);
return kConstantPoolRegister;
#else
UNREACHABLE();
return no_reg;
#endif
}
Register StubFailureTrampolineFrame::fp_register() { return v8::internal::fp; }
Register StubFailureTrampolineFrame::context_register() { return cp; }
Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
#if V8_OOL_CONSTANT_POOL
DCHECK(FLAG_enable_ool_constant_pool);
return kConstantPoolRegister;
#else
UNREACHABLE();
return no_reg;
#endif
}
Object*& ExitFrame::constant_pool_slot() const {
#if V8_OOL_CONSTANT_POOL
DCHECK(FLAG_enable_ool_constant_pool);
const int offset = ExitFrameConstants::kConstantPoolOffset;
return Memory::Object_at(fp() + offset);
#else
UNREACHABLE();
return Memory::Object_at(NULL);
#endif
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_PPC
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_PPC_FRAMES_PPC_H_
#define V8_PPC_FRAMES_PPC_H_
namespace v8 {
namespace internal {
// Register list in load/store instructions
// Note that the bit values must match those used in actual instruction encoding
const int kNumRegs = 32;
// Caller-saved/arguments registers
const RegList kJSCallerSaved = 1 << 3 | // r3 a1
1 << 4 | // r4 a2
1 << 5 | // r5 a3
1 << 6 | // r6 a4
1 << 7 | // r7 a5
1 << 8 | // r8 a6
1 << 9 | // r9 a7
1 << 10 | // r10 a8
1 << 11;
const int kNumJSCallerSaved = 9;
// Return the code of the n-th caller-saved register available to JavaScript
// e.g. JSCallerSavedReg(0) returns r0.code() == 0
int JSCallerSavedCode(int n);
// Callee-saved registers preserved when switching from C to JavaScript
const RegList kCalleeSaved = 1 << 14 | // r14
1 << 15 | // r15
1 << 16 | // r16
1 << 17 | // r17
1 << 18 | // r18
1 << 19 | // r19
1 << 20 | // r20
1 << 21 | // r21
1 << 22 | // r22
1 << 23 | // r23
1 << 24 | // r24
1 << 25 | // r25
1 << 26 | // r26
1 << 27 | // r27
1 << 28 | // r28
1 << 29 | // r29
1 << 30 | // r20
1 << 31; // r31
const int kNumCalleeSaved = 18;
// Number of registers for which space is reserved in safepoints. Must be a
// multiple of 8.
// TODO(regis): Only 8 registers may actually be sufficient. Revisit.
const int kNumSafepointRegisters = 32;
// Define the list of registers actually saved at safepoints.
// Note that the number of saved registers may be smaller than the reserved
// space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
// The following constants describe the stack frame linkage area as
// defined by the ABI. Note that kNumRequiredStackFrameSlots must
// satisfy alignment requirements (rounding up if required).
#if V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN
// [0] back chain
// [1] condition register save area
// [2] link register save area
// [3] TOC save area
// [4] Parameter1 save area
// ...
// [11] Parameter8 save area
// [12] Parameter9 slot (if necessary)
// ...
const int kNumRequiredStackFrameSlots = 12;
const int kStackFrameLRSlot = 2;
const int kStackFrameExtraParamSlot = 12;
#elif V8_OS_AIX || V8_TARGET_ARCH_PPC64
// [0] back chain
// [1] condition register save area
// [2] link register save area
// [3] reserved for compiler
// [4] reserved by binder
// [5] TOC save area
// [6] Parameter1 save area
// ...
// [13] Parameter8 save area
// [14] Parameter9 slot (if necessary)
// ...
#if V8_TARGET_ARCH_PPC64
const int kNumRequiredStackFrameSlots = 14;
#else
const int kNumRequiredStackFrameSlots = 16;
#endif
const int kStackFrameLRSlot = 2;
const int kStackFrameExtraParamSlot = 14;
#else
// [0] back chain
// [1] link register save area
// [2] Parameter9 slot (if necessary)
// ...
const int kNumRequiredStackFrameSlots = 4;
const int kStackFrameLRSlot = 1;
const int kStackFrameExtraParamSlot = 2;
#endif
// ----------------------------------------------------
class EntryFrameConstants : public AllStatic {
public:
static const int kCallerFPOffset =
-(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
};
class ExitFrameConstants : public AllStatic {
public:
#if V8_OOL_CONSTANT_POOL
static const int kFrameSize = 3 * kPointerSize;
static const int kConstantPoolOffset = -3 * kPointerSize;
#else
static const int kFrameSize = 2 * kPointerSize;
static const int kConstantPoolOffset = 0; // Not used.
#endif
static const int kCodeOffset = -2 * kPointerSize;
static const int kSPOffset = -1 * kPointerSize;
// The caller fields are below the frame pointer on the stack.
static const int kCallerFPOffset = 0 * kPointerSize;
// The calling JS function is below FP.
static const int kCallerPCOffset = 1 * kPointerSize;
// FP-relative displacement of the caller's SP. It points just
// below the saved PC.
static const int kCallerSPDisplacement = 2 * kPointerSize;
};
class JavaScriptFrameConstants : public AllStatic {
public:
// FP-relative.
static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
static const int kLastParameterOffset = +2 * kPointerSize;
static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
// Caller SP-relative.
static const int kParam0Offset = -2 * kPointerSize;
static const int kReceiverOffset = -1 * kPointerSize;
};
class ArgumentsAdaptorFrameConstants : public AllStatic {
public:
// FP-relative.
static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
static const int kFrameSize =
StandardFrameConstants::kFixedFrameSize + kPointerSize;
};
class ConstructFrameConstants : public AllStatic {
public:
// FP-relative.
static const int kImplicitReceiverOffset = -6 * kPointerSize;
static const int kConstructorOffset = -5 * kPointerSize;
static const int kLengthOffset = -4 * kPointerSize;
static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
static const int kFrameSize =
StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
};
class InternalFrameConstants : public AllStatic {
public:
// FP-relative.
static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
};
inline Object* JavaScriptFrame::function_slot_object() const {
const int offset = JavaScriptFrameConstants::kFunctionOffset;
return Memory::Object_at(fp() + offset);
}
inline void StackHandler::SetFp(Address slot, Address fp) {
Memory::Address_at(slot) = fp;
}
}
} // namespace v8::internal
#endif // V8_PPC_FRAMES_PPC_H_
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment