v8/test/cctest/test-constantpool.cc
mbrandy eac7f04669 Add support for Embedded Constant Pools for PPC and Arm
Embed constant pools within their corresponding Code
objects.

This removes support for out-of-line constant pools in favor
of the new approach -- the main advantage being that it
eliminates the need to allocate and manage separate constant
pool array objects.

Currently supported on PPC and ARM.  Enabled by default on
PPC only.

This yields a 6% improvment in Octane on PPC64.

R=bmeurer@chromium.org, rmcilroy@chromium.org, michael_dawson@ca.ibm.com
BUG=chromium:478811
LOG=Y

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

Cr-Commit-Position: refs/heads/master@{#28801}
2015-06-04 14:44:15 +00:00

248 lines
6.9 KiB
C++

// Copyright 2015 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.
// Test embedded constant pool builder code.
#include "src/v8.h"
#include "src/assembler.h"
#include "test/cctest/cctest.h"
using namespace v8::internal;
const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR;
const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE;
const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR;
const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED;
const int kReachBits = 6; // Use reach of 64-bytes to test overflow.
const int kReach = 1 << kReachBits;
TEST(ConstantPoolPointers) {
ConstantPoolBuilder builder(kReachBits, kReachBits);
const int kRegularCount = kReach / kPointerSize;
ConstantPoolEntry::Access access;
int pos = 0;
intptr_t value = 0;
bool sharing_ok = true;
CHECK(builder.IsEmpty());
while (builder.NextAccess(kPtrType) == kRegAccess) {
access = builder.AddEntry(pos++, value++, sharing_ok);
CHECK_EQ(access, kRegAccess);
}
CHECK(!builder.IsEmpty());
CHECK_EQ(pos, kRegularCount);
access = builder.AddEntry(pos, value, sharing_ok);
CHECK_EQ(access, kOvflAccess);
}
TEST(ConstantPoolDoubles) {
ConstantPoolBuilder builder(kReachBits, kReachBits);
const int kRegularCount = kReach / kDoubleSize;
ConstantPoolEntry::Access access;
int pos = 0;
double value = 0.0;
CHECK(builder.IsEmpty());
while (builder.NextAccess(kDblType) == kRegAccess) {
access = builder.AddEntry(pos++, value);
value += 0.5;
CHECK_EQ(access, kRegAccess);
}
CHECK(!builder.IsEmpty());
CHECK_EQ(pos, kRegularCount);
access = builder.AddEntry(pos, value);
CHECK_EQ(access, kOvflAccess);
}
TEST(ConstantPoolMixedTypes) {
ConstantPoolBuilder builder(kReachBits, kReachBits);
const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
((kPointerSize < kDoubleSize) ? 1 : 0));
ConstantPoolEntry::Type type = kPtrType;
ConstantPoolEntry::Access access;
int pos = 0;
intptr_t ptrValue = 0;
double dblValue = 0.0;
bool sharing_ok = true;
CHECK(builder.IsEmpty());
while (builder.NextAccess(type) == kRegAccess) {
if (type == kPtrType) {
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
type = kDblType;
} else {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
type = kPtrType;
}
CHECK_EQ(access, kRegAccess);
}
CHECK(!builder.IsEmpty());
CHECK_EQ(pos, kRegularCount);
access = builder.AddEntry(pos++, ptrValue, sharing_ok);
CHECK_EQ(access, kOvflAccess);
access = builder.AddEntry(pos, dblValue);
CHECK_EQ(access, kOvflAccess);
}
TEST(ConstantPoolMixedReach) {
const int ptrReachBits = kReachBits + 2;
const int ptrReach = 1 << ptrReachBits;
const int dblReachBits = kReachBits;
const int dblReach = kReach;
const int dblRegularCount =
Min(dblReach / kDoubleSize, ptrReach / (kDoubleSize + kPointerSize));
const int ptrRegularCount =
((ptrReach - (dblRegularCount * (kDoubleSize + kPointerSize))) /
kPointerSize) +
dblRegularCount;
ConstantPoolBuilder builder(ptrReachBits, dblReachBits);
ConstantPoolEntry::Access access;
int pos = 0;
intptr_t ptrValue = 0;
double dblValue = 0.0;
bool sharing_ok = true;
int ptrCount = 0;
int dblCount = 0;
CHECK(builder.IsEmpty());
while (builder.NextAccess(kDblType) == kRegAccess) {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
dblCount++;
CHECK_EQ(access, kRegAccess);
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
ptrCount++;
CHECK_EQ(access, kRegAccess);
}
CHECK(!builder.IsEmpty());
CHECK_EQ(dblCount, dblRegularCount);
while (ptrCount < ptrRegularCount) {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
CHECK_EQ(access, kOvflAccess);
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
ptrCount++;
CHECK_EQ(access, kRegAccess);
}
CHECK_EQ(builder.NextAccess(kPtrType), kOvflAccess);
access = builder.AddEntry(pos++, ptrValue, sharing_ok);
CHECK_EQ(access, kOvflAccess);
access = builder.AddEntry(pos, dblValue);
CHECK_EQ(access, kOvflAccess);
}
TEST(ConstantPoolSharing) {
ConstantPoolBuilder builder(kReachBits, kReachBits);
const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
((kPointerSize < kDoubleSize) ? 1 : 0));
ConstantPoolEntry::Access access;
CHECK(builder.IsEmpty());
ConstantPoolEntry::Type type = kPtrType;
int pos = 0;
intptr_t ptrValue = 0;
double dblValue = 0.0;
bool sharing_ok = true;
while (builder.NextAccess(type) == kRegAccess) {
if (type == kPtrType) {
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
type = kDblType;
} else {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
type = kPtrType;
}
CHECK_EQ(access, kRegAccess);
}
CHECK(!builder.IsEmpty());
CHECK_EQ(pos, kRegularCount);
type = kPtrType;
ptrValue = 0;
dblValue = 0.0;
while (pos < kRegularCount * 2) {
if (type == kPtrType) {
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
type = kDblType;
} else {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
type = kPtrType;
}
CHECK_EQ(access, kRegAccess);
}
access = builder.AddEntry(pos++, ptrValue, sharing_ok);
CHECK_EQ(access, kOvflAccess);
access = builder.AddEntry(pos, dblValue);
CHECK_EQ(access, kOvflAccess);
}
TEST(ConstantPoolNoSharing) {
ConstantPoolBuilder builder(kReachBits, kReachBits);
const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
((kPointerSize < kDoubleSize) ? 1 : 0));
ConstantPoolEntry::Access access;
CHECK(builder.IsEmpty());
ConstantPoolEntry::Type type = kPtrType;
int pos = 0;
intptr_t ptrValue = 0;
double dblValue = 0.0;
bool sharing_ok = false;
while (builder.NextAccess(type) == kRegAccess) {
if (type == kPtrType) {
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
type = kDblType;
} else {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
type = kPtrType;
}
CHECK_EQ(access, kRegAccess);
}
CHECK(!builder.IsEmpty());
CHECK_EQ(pos, kRegularCount);
type = kPtrType;
ptrValue = 0;
dblValue = 0.0;
sharing_ok = true;
while (pos < kRegularCount * 2) {
if (type == kPtrType) {
access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
type = kDblType;
CHECK_EQ(access, kOvflAccess);
} else {
access = builder.AddEntry(pos++, dblValue);
dblValue += 0.5;
type = kPtrType;
CHECK_EQ(access, kRegAccess);
}
}
access = builder.AddEntry(pos++, ptrValue, sharing_ok);
CHECK_EQ(access, kOvflAccess);
access = builder.AddEntry(pos, dblValue);
CHECK_EQ(access, kOvflAccess);
}