| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits> | 5 #include <limits> |
| 6 | 6 |
| 7 #include "src/compiler/control-builders.h" | 7 #include "src/compiler/control-builders.h" |
| 8 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
| 9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
| 10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 Factory* factory() { return this->isolate()->factory(); } | 80 Factory* factory() { return this->isolate()->factory(); } |
| 81 Heap* heap() { return this->isolate()->heap(); } | 81 Heap* heap() { return this->isolate()->heap(); } |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 | 84 |
| 85 // TODO(dcarney): find a home for these functions. | 85 // TODO(dcarney): find a home for these functions. |
| 86 namespace { | 86 namespace { |
| 87 | 87 |
| 88 FieldAccess ForJSObjectMap() { | 88 FieldAccess ForJSObjectMap() { |
| 89 FieldAccess access = {JSObject::kMapOffset, Handle<Name>(), Type::Any(), | 89 FieldAccess access = {kTaggedBase, JSObject::kMapOffset, Handle<Name>(), |
| 90 kMachineTagged}; | 90 Type::Any(), kMachineTagged}; |
| 91 return access; | 91 return access; |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 FieldAccess ForJSObjectProperties() { | 95 FieldAccess ForJSObjectProperties() { |
| 96 FieldAccess access = {JSObject::kPropertiesOffset, Handle<Name>(), | 96 FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset, |
| 97 Type::Any(), kMachineTagged}; | 97 Handle<Name>(), Type::Any(), kMachineTagged}; |
| 98 return access; | 98 return access; |
| 99 } | 99 } |
| 100 | 100 |
| 101 | 101 |
| 102 FieldAccess ForArrayBufferBackingStore() { | 102 FieldAccess ForArrayBufferBackingStore() { |
| 103 FieldAccess access = { | 103 FieldAccess access = { |
| 104 JSArrayBuffer::kBackingStoreOffset, Handle<Name>(), Type::UntaggedPtr(), | 104 kTaggedBase, JSArrayBuffer::kBackingStoreOffset, |
| 105 Handle<Name>(), Type::UntaggedPtr(), |
| 105 MachineOperatorBuilder::pointer_rep(), | 106 MachineOperatorBuilder::pointer_rep(), |
| 106 }; | 107 }; |
| 107 return access; | 108 return access; |
| 108 } | 109 } |
| 109 | 110 |
| 110 | 111 |
| 111 ElementAccess ForFixedArrayElement() { | 112 ElementAccess ForFixedArrayElement() { |
| 112 ElementAccess access = {FixedArray::kHeaderSize, Type::Any(), kMachineTagged}; | 113 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), |
| 114 kMachineTagged}; |
| 113 return access; | 115 return access; |
| 114 } | 116 } |
| 115 | 117 |
| 116 | 118 |
| 117 ElementAccess ForBackingStoreElement(MachineRepresentation rep) { | 119 ElementAccess ForBackingStoreElement(MachineRepresentation rep) { |
| 118 ElementAccess access = {kNonHeapObjectHeaderSize, Type::Any(), rep}; | 120 ElementAccess access = {kUntaggedBase, |
| 121 kNonHeapObjectHeaderSize - kHeapObjectTag, |
| 122 Type::Any(), rep}; |
| 119 return access; | 123 return access; |
| 120 } | 124 } |
| 121 } | 125 } |
| 122 | 126 |
| 123 | 127 |
| 124 // Create a simple JSObject with a unique map. | 128 // Create a simple JSObject with a unique map. |
| 125 static Handle<JSObject> TestObject() { | 129 static Handle<JSObject> TestObject() { |
| 126 static int index = 0; | 130 static int index = 0; |
| 127 char buffer[50]; | 131 char buffer[50]; |
| 128 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 132 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 src->set(i, *TestObject()); | 308 src->set(i, *TestObject()); |
| 305 src_copy->set(i, src->get(i)); | 309 src_copy->set(i, src->get(i)); |
| 306 dst->set(i, *TestObject()); | 310 dst->set(i, *TestObject()); |
| 307 CHECK_NE(src_copy->get(i), dst->get(i)); | 311 CHECK_NE(src_copy->get(i), dst->get(i)); |
| 308 } | 312 } |
| 309 CHECK_EQ(kArraySize, t.Call(*src, *dst)); | 313 CHECK_EQ(kArraySize, t.Call(*src, *dst)); |
| 310 for (int i = 0; i < kArraySize; i++) { | 314 for (int i = 0; i < kArraySize; i++) { |
| 311 CHECK_EQ(src_copy->get(i), dst->get(i)); | 315 CHECK_EQ(src_copy->get(i), dst->get(i)); |
| 312 } | 316 } |
| 313 } | 317 } |
| 318 |
| 319 |
| 320 TEST(RunLoadFieldFromUntaggedBase) { |
| 321 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
| 322 |
| 323 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { |
| 324 FieldAccess access = {kUntaggedBase, // untagged base |
| 325 i * sizeof(Smi*), // offset |
| 326 Handle<Name>(), Type::Integral32(), kMachineTagged}; |
| 327 |
| 328 SimplifiedGraphBuilderTester<Object*> t; |
| 329 Node* load = t.LoadField(access, t.PointerConstant(smis)); |
| 330 t.Return(load); |
| 331 t.LowerAllNodes(); |
| 332 |
| 333 for (int j = -5; j <= 5; j++) { |
| 334 Smi* expected = Smi::FromInt(j); |
| 335 smis[i] = expected; |
| 336 CHECK_EQ(expected, t.Call()); |
| 337 } |
| 338 } |
| 339 } |
| 340 |
| 341 |
| 342 TEST(RunStoreFieldToUntaggedBase) { |
| 343 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
| 344 |
| 345 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { |
| 346 FieldAccess access = {kUntaggedBase, // untagged base |
| 347 i * sizeof(Smi*), // offset |
| 348 Handle<Name>(), Type::Integral32(), kMachineTagged}; |
| 349 |
| 350 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); |
| 351 Node* p0 = t.Parameter(0); |
| 352 t.StoreField(access, t.PointerConstant(smis), p0); |
| 353 t.Return(p0); |
| 354 t.LowerAllNodes(); |
| 355 |
| 356 for (int j = -5; j <= 5; j++) { |
| 357 Smi* expected = Smi::FromInt(j); |
| 358 smis[i] = Smi::FromInt(-100); |
| 359 CHECK_EQ(expected, t.Call(expected)); |
| 360 CHECK_EQ(expected, smis[i]); |
| 361 } |
| 362 } |
| 363 } |
| 364 |
| 365 |
| 366 TEST(RunLoadElementFromUntaggedBase) { |
| 367 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
| 368 Smi::FromInt(4), Smi::FromInt(5)}; |
| 369 |
| 370 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes |
| 371 for (size_t j = i; j < ARRAY_SIZE(smis); j++) { // for element index |
| 372 ElementAccess access = {kUntaggedBase, // untagged base |
| 373 i * sizeof(Smi*), // header size |
| 374 Type::Integral32(), kMachineTagged}; |
| 375 |
| 376 SimplifiedGraphBuilderTester<Object*> t; |
| 377 Node* load = |
| 378 t.LoadElement(access, t.PointerConstant(smis), t.Int32Constant(j)); |
| 379 t.Return(load); |
| 380 t.LowerAllNodes(); |
| 381 |
| 382 for (int k = -5; k <= 5; k++) { |
| 383 Smi* expected = Smi::FromInt(k); |
| 384 smis[i + j] = expected; |
| 385 CHECK_EQ(expected, t.Call()); |
| 386 } |
| 387 } |
| 388 } |
| 389 } |
| 390 |
| 391 |
| 392 TEST(RunStoreElementFromUntaggedBase) { |
| 393 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
| 394 Smi::FromInt(4), Smi::FromInt(5)}; |
| 395 |
| 396 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes |
| 397 for (size_t j = i; j < ARRAY_SIZE(smis); j++) { // for element index |
| 398 ElementAccess access = {kUntaggedBase, // untagged base |
| 399 i * sizeof(Smi*), // header size |
| 400 Type::Integral32(), kMachineTagged}; |
| 401 |
| 402 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); |
| 403 Node* p0 = t.Parameter(0); |
| 404 t.StoreElement(access, t.PointerConstant(smis), t.Int32Constant(j), p0); |
| 405 t.Return(p0); |
| 406 t.LowerAllNodes(); |
| 407 |
| 408 for (int k = -5; k <= 5; k++) { |
| 409 Smi* expected = Smi::FromInt(k); |
| 410 smis[i + j] = Smi::FromInt(-100); |
| 411 CHECK_EQ(expected, t.Call(expected)); |
| 412 CHECK_EQ(expected, smis[i + j]); |
| 413 } |
| 414 } |
| 415 } |
| 416 } |
| OLD | NEW |