eac7f04669
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}
248 lines
6.9 KiB
C++
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);
|
|
}
|