|  | // 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/init/v8.h" | 
|  |  | 
|  | #include "src/codegen/constant-pool.h" | 
|  | #include "test/cctest/cctest.h" | 
|  |  | 
|  | namespace v8 { | 
|  | namespace internal { | 
|  |  | 
|  | #if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64) | 
|  |  | 
|  | 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 / kSystemPointerSize; | 
|  | 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 + kSystemPointerSize)) * 2) + | 
|  | ((kSystemPointerSize < 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 + kSystemPointerSize)); | 
|  | const int ptrRegularCount = | 
|  | ((ptrReach - (dblRegularCount * (kDoubleSize + kSystemPointerSize))) / | 
|  | kSystemPointerSize) + | 
|  | 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 + kSystemPointerSize)) * 2) + | 
|  | ((kSystemPointerSize < 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 + kSystemPointerSize)) * 2) + | 
|  | ((kSystemPointerSize < 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); | 
|  | } | 
|  |  | 
|  | #endif  // defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64) | 
|  |  | 
|  | }  // namespace internal | 
|  | }  // namespace v8 |