1// Copyright 2015 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Test embedded constant pool builder code. 6 7#include "src/v8.h" 8 9#include "src/assembler.h" 10#include "test/cctest/cctest.h" 11 12using namespace v8::internal; 13 14const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR; 15const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE; 16const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR; 17const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED; 18 19const int kReachBits = 6; // Use reach of 64-bytes to test overflow. 20const int kReach = 1 << kReachBits; 21 22 23TEST(ConstantPoolPointers) { 24 ConstantPoolBuilder builder(kReachBits, kReachBits); 25 const int kRegularCount = kReach / kPointerSize; 26 ConstantPoolEntry::Access access; 27 int pos = 0; 28 intptr_t value = 0; 29 bool sharing_ok = true; 30 31 CHECK(builder.IsEmpty()); 32 while (builder.NextAccess(kPtrType) == kRegAccess) { 33 access = builder.AddEntry(pos++, value++, sharing_ok); 34 CHECK_EQ(access, kRegAccess); 35 } 36 CHECK(!builder.IsEmpty()); 37 CHECK_EQ(pos, kRegularCount); 38 39 access = builder.AddEntry(pos, value, sharing_ok); 40 CHECK_EQ(access, kOvflAccess); 41} 42 43 44TEST(ConstantPoolDoubles) { 45 ConstantPoolBuilder builder(kReachBits, kReachBits); 46 const int kRegularCount = kReach / kDoubleSize; 47 ConstantPoolEntry::Access access; 48 int pos = 0; 49 double value = 0.0; 50 51 CHECK(builder.IsEmpty()); 52 while (builder.NextAccess(kDblType) == kRegAccess) { 53 access = builder.AddEntry(pos++, value); 54 value += 0.5; 55 CHECK_EQ(access, kRegAccess); 56 } 57 CHECK(!builder.IsEmpty()); 58 CHECK_EQ(pos, kRegularCount); 59 60 access = builder.AddEntry(pos, value); 61 CHECK_EQ(access, kOvflAccess); 62} 63 64 65TEST(ConstantPoolMixedTypes) { 66 ConstantPoolBuilder builder(kReachBits, kReachBits); 67 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) + 68 ((kPointerSize < kDoubleSize) ? 1 : 0)); 69 ConstantPoolEntry::Type type = kPtrType; 70 ConstantPoolEntry::Access access; 71 int pos = 0; 72 intptr_t ptrValue = 0; 73 double dblValue = 0.0; 74 bool sharing_ok = true; 75 76 CHECK(builder.IsEmpty()); 77 while (builder.NextAccess(type) == kRegAccess) { 78 if (type == kPtrType) { 79 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 80 type = kDblType; 81 } else { 82 access = builder.AddEntry(pos++, dblValue); 83 dblValue += 0.5; 84 type = kPtrType; 85 } 86 CHECK_EQ(access, kRegAccess); 87 } 88 CHECK(!builder.IsEmpty()); 89 CHECK_EQ(pos, kRegularCount); 90 91 access = builder.AddEntry(pos++, ptrValue, sharing_ok); 92 CHECK_EQ(access, kOvflAccess); 93 access = builder.AddEntry(pos, dblValue); 94 CHECK_EQ(access, kOvflAccess); 95} 96 97 98TEST(ConstantPoolMixedReach) { 99 const int ptrReachBits = kReachBits + 2; 100 const int ptrReach = 1 << ptrReachBits; 101 const int dblReachBits = kReachBits; 102 const int dblReach = kReach; 103 const int dblRegularCount = 104 Min(dblReach / kDoubleSize, ptrReach / (kDoubleSize + kPointerSize)); 105 const int ptrRegularCount = 106 ((ptrReach - (dblRegularCount * (kDoubleSize + kPointerSize))) / 107 kPointerSize) + 108 dblRegularCount; 109 ConstantPoolBuilder builder(ptrReachBits, dblReachBits); 110 ConstantPoolEntry::Access access; 111 int pos = 0; 112 intptr_t ptrValue = 0; 113 double dblValue = 0.0; 114 bool sharing_ok = true; 115 int ptrCount = 0; 116 int dblCount = 0; 117 118 CHECK(builder.IsEmpty()); 119 while (builder.NextAccess(kDblType) == kRegAccess) { 120 access = builder.AddEntry(pos++, dblValue); 121 dblValue += 0.5; 122 dblCount++; 123 CHECK_EQ(access, kRegAccess); 124 125 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 126 ptrCount++; 127 CHECK_EQ(access, kRegAccess); 128 } 129 CHECK(!builder.IsEmpty()); 130 CHECK_EQ(dblCount, dblRegularCount); 131 132 while (ptrCount < ptrRegularCount) { 133 access = builder.AddEntry(pos++, dblValue); 134 dblValue += 0.5; 135 CHECK_EQ(access, kOvflAccess); 136 137 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 138 ptrCount++; 139 CHECK_EQ(access, kRegAccess); 140 } 141 CHECK_EQ(builder.NextAccess(kPtrType), kOvflAccess); 142 143 access = builder.AddEntry(pos++, ptrValue, sharing_ok); 144 CHECK_EQ(access, kOvflAccess); 145 access = builder.AddEntry(pos, dblValue); 146 CHECK_EQ(access, kOvflAccess); 147} 148 149 150TEST(ConstantPoolSharing) { 151 ConstantPoolBuilder builder(kReachBits, kReachBits); 152 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) + 153 ((kPointerSize < kDoubleSize) ? 1 : 0)); 154 ConstantPoolEntry::Access access; 155 156 CHECK(builder.IsEmpty()); 157 158 ConstantPoolEntry::Type type = kPtrType; 159 int pos = 0; 160 intptr_t ptrValue = 0; 161 double dblValue = 0.0; 162 bool sharing_ok = true; 163 while (builder.NextAccess(type) == kRegAccess) { 164 if (type == kPtrType) { 165 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 166 type = kDblType; 167 } else { 168 access = builder.AddEntry(pos++, dblValue); 169 dblValue += 0.5; 170 type = kPtrType; 171 } 172 CHECK_EQ(access, kRegAccess); 173 } 174 CHECK(!builder.IsEmpty()); 175 CHECK_EQ(pos, kRegularCount); 176 177 type = kPtrType; 178 ptrValue = 0; 179 dblValue = 0.0; 180 while (pos < kRegularCount * 2) { 181 if (type == kPtrType) { 182 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 183 type = kDblType; 184 } else { 185 access = builder.AddEntry(pos++, dblValue); 186 dblValue += 0.5; 187 type = kPtrType; 188 } 189 CHECK_EQ(access, kRegAccess); 190 } 191 192 access = builder.AddEntry(pos++, ptrValue, sharing_ok); 193 CHECK_EQ(access, kOvflAccess); 194 access = builder.AddEntry(pos, dblValue); 195 CHECK_EQ(access, kOvflAccess); 196} 197 198 199TEST(ConstantPoolNoSharing) { 200 ConstantPoolBuilder builder(kReachBits, kReachBits); 201 const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) + 202 ((kPointerSize < kDoubleSize) ? 1 : 0)); 203 ConstantPoolEntry::Access access; 204 205 CHECK(builder.IsEmpty()); 206 207 ConstantPoolEntry::Type type = kPtrType; 208 int pos = 0; 209 intptr_t ptrValue = 0; 210 double dblValue = 0.0; 211 bool sharing_ok = false; 212 while (builder.NextAccess(type) == kRegAccess) { 213 if (type == kPtrType) { 214 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 215 type = kDblType; 216 } else { 217 access = builder.AddEntry(pos++, dblValue); 218 dblValue += 0.5; 219 type = kPtrType; 220 } 221 CHECK_EQ(access, kRegAccess); 222 } 223 CHECK(!builder.IsEmpty()); 224 CHECK_EQ(pos, kRegularCount); 225 226 type = kPtrType; 227 ptrValue = 0; 228 dblValue = 0.0; 229 sharing_ok = true; 230 while (pos < kRegularCount * 2) { 231 if (type == kPtrType) { 232 access = builder.AddEntry(pos++, ptrValue++, sharing_ok); 233 type = kDblType; 234 CHECK_EQ(access, kOvflAccess); 235 } else { 236 access = builder.AddEntry(pos++, dblValue); 237 dblValue += 0.5; 238 type = kPtrType; 239 CHECK_EQ(access, kRegAccess); 240 } 241 } 242 243 access = builder.AddEntry(pos++, ptrValue, sharing_ok); 244 CHECK_EQ(access, kOvflAccess); 245 access = builder.AddEntry(pos, dblValue); 246 CHECK_EQ(access, kOvflAccess); 247} 248