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 = {true, JSObject::kMapOffset, Handle<Name>(), Type::Any(), |
Benedikt Meurer
2014/08/04 11:53:57
Can we have an enum here? Free-floating true/false
| |
90 kMachineTagged}; | 90 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 = {true, JSObject::kPropertiesOffset, Handle<Name>(), |
97 Type::Any(), kMachineTagged}; | 97 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 true, 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 = {true, 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 = {false, kNonHeapObjectHeaderSize - kHeapObjectTag, |
121 Type::Any(), rep}; | |
119 return access; | 122 return access; |
120 } | 123 } |
121 } | 124 } |
122 | 125 |
123 | 126 |
124 // Create a simple JSObject with a unique map. | 127 // Create a simple JSObject with a unique map. |
125 static Handle<JSObject> TestObject() { | 128 static Handle<JSObject> TestObject() { |
126 static int index = 0; | 129 static int index = 0; |
127 char buffer[50]; | 130 char buffer[50]; |
128 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 131 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()); | 307 src->set(i, *TestObject()); |
305 src_copy->set(i, src->get(i)); | 308 src_copy->set(i, src->get(i)); |
306 dst->set(i, *TestObject()); | 309 dst->set(i, *TestObject()); |
307 CHECK_NE(src_copy->get(i), dst->get(i)); | 310 CHECK_NE(src_copy->get(i), dst->get(i)); |
308 } | 311 } |
309 CHECK_EQ(kArraySize, t.Call(*src, *dst)); | 312 CHECK_EQ(kArraySize, t.Call(*src, *dst)); |
310 for (int i = 0; i < kArraySize; i++) { | 313 for (int i = 0; i < kArraySize; i++) { |
311 CHECK_EQ(src_copy->get(i), dst->get(i)); | 314 CHECK_EQ(src_copy->get(i), dst->get(i)); |
312 } | 315 } |
313 } | 316 } |
317 | |
318 | |
319 TEST(RunLoadFieldFromUntaggedBase) { | |
320 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | |
321 | |
322 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { | |
323 FieldAccess access = {false, // untagged base | |
324 i * sizeof(Smi*), // offset | |
325 Handle<Name>(), Type::Integral32(), kMachineTagged}; | |
326 | |
327 SimplifiedGraphBuilderTester<Object*> t; | |
328 Node* load = t.LoadField(access, t.PointerConstant(smis)); | |
329 t.Return(load); | |
330 t.LowerAllNodes(); | |
331 | |
332 for (int j = -5; j <= 5; j++) { | |
333 Smi* expected = Smi::FromInt(j); | |
334 smis[i] = expected; | |
335 CHECK_EQ(expected, t.Call()); | |
336 } | |
337 } | |
338 } | |
339 | |
340 | |
341 TEST(RunStoreFieldToUntaggedBase) { | |
342 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | |
343 | |
344 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { | |
345 FieldAccess access = {false, // untagged base | |
346 i * sizeof(Smi*), // offset | |
347 Handle<Name>(), Type::Integral32(), kMachineTagged}; | |
348 | |
349 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); | |
350 Node* p0 = t.Parameter(0); | |
351 t.StoreField(access, t.PointerConstant(smis), p0); | |
352 t.Return(p0); | |
353 t.LowerAllNodes(); | |
354 | |
355 for (int j = -5; j <= 5; j++) { | |
356 Smi* expected = Smi::FromInt(j); | |
357 smis[i] = Smi::FromInt(-100); | |
358 CHECK_EQ(expected, t.Call(expected)); | |
359 CHECK_EQ(expected, smis[i]); | |
360 } | |
361 } | |
362 } | |
363 | |
364 | |
365 TEST(RunLoadElementFromUntaggedBase) { | |
366 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | |
367 Smi::FromInt(4), Smi::FromInt(5)}; | |
368 | |
369 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes | |
370 for (size_t j = i; j < ARRAY_SIZE(smis); j++) { // for element index | |
371 ElementAccess access = {false, // untagged base | |
372 i * sizeof(Smi*), // header size | |
373 Type::Integral32(), kMachineTagged}; | |
374 | |
375 SimplifiedGraphBuilderTester<Object*> t; | |
376 Node* load = | |
377 t.LoadElement(access, t.PointerConstant(smis), t.Int32Constant(j)); | |
378 t.Return(load); | |
379 t.LowerAllNodes(); | |
380 | |
381 for (int k = -5; k <= 5; k++) { | |
382 Smi* expected = Smi::FromInt(k); | |
383 smis[i + j] = expected; | |
384 CHECK_EQ(expected, t.Call()); | |
385 } | |
386 } | |
387 } | |
388 } | |
389 | |
390 | |
391 TEST(RunStoreElementFromUntaggedBase) { | |
392 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | |
393 Smi::FromInt(4), Smi::FromInt(5)}; | |
394 | |
395 for (size_t i = 0; i < ARRAY_SIZE(smis); i++) { // for header sizes | |
396 for (size_t j = i; j < ARRAY_SIZE(smis); j++) { // for element index | |
397 ElementAccess access = {false, // untagged base | |
398 i * sizeof(Smi*), // header size | |
399 Type::Integral32(), kMachineTagged}; | |
400 | |
401 SimplifiedGraphBuilderTester<Object*> t(kMachineTagged); | |
402 Node* p0 = t.Parameter(0); | |
403 t.StoreElement(access, t.PointerConstant(smis), t.Int32Constant(j), p0); | |
404 t.Return(p0); | |
405 t.LowerAllNodes(); | |
406 | |
407 for (int k = -5; k <= 5; k++) { | |
408 Smi* expected = Smi::FromInt(k); | |
409 smis[i + j] = Smi::FromInt(-100); | |
410 CHECK_EQ(expected, t.Call(expected)); | |
411 CHECK_EQ(expected, smis[i + j]); | |
412 } | |
413 } | |
414 } | |
415 } | |
OLD | NEW |