| 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/access-builder.h" |
| 7 #include "src/compiler/control-builders.h" | 8 #include "src/compiler/control-builders.h" |
| 8 #include "src/compiler/generic-node-inl.h" | 9 #include "src/compiler/generic-node-inl.h" |
| 9 #include "src/compiler/graph-visualizer.h" | 10 #include "src/compiler/graph-visualizer.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 11 #include "src/compiler/node-properties-inl.h" |
| 11 #include "src/compiler/pipeline.h" | 12 #include "src/compiler/pipeline.h" |
| 12 #include "src/compiler/representation-change.h" | 13 #include "src/compiler/representation-change.h" |
| 13 #include "src/compiler/simplified-lowering.h" | 14 #include "src/compiler/simplified-lowering.h" |
| 14 #include "src/compiler/simplified-node-factory.h" | 15 #include "src/compiler/simplified-node-factory.h" |
| 15 #include "src/compiler/typer.h" | 16 #include "src/compiler/typer.h" |
| 16 #include "src/compiler/verifier.h" | 17 #include "src/compiler/verifier.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 46 void LowerAllNodes() { | 47 void LowerAllNodes() { |
| 47 this->End(); | 48 this->End(); |
| 48 lowering.LowerAllNodes(); | 49 lowering.LowerAllNodes(); |
| 49 } | 50 } |
| 50 | 51 |
| 51 Factory* factory() { return this->isolate()->factory(); } | 52 Factory* factory() { return this->isolate()->factory(); } |
| 52 Heap* heap() { return this->isolate()->heap(); } | 53 Heap* heap() { return this->isolate()->heap(); } |
| 53 }; | 54 }; |
| 54 | 55 |
| 55 | 56 |
| 56 // TODO(dcarney): find a home for these functions. | |
| 57 namespace { | |
| 58 | |
| 59 FieldAccess ForJSObjectMap() { | |
| 60 FieldAccess access = {kTaggedBase, JSObject::kMapOffset, Handle<Name>(), | |
| 61 Type::Any(), kMachAnyTagged}; | |
| 62 return access; | |
| 63 } | |
| 64 | |
| 65 | |
| 66 FieldAccess ForJSObjectProperties() { | |
| 67 FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset, | |
| 68 Handle<Name>(), Type::Any(), kMachAnyTagged}; | |
| 69 return access; | |
| 70 } | |
| 71 | |
| 72 | |
| 73 FieldAccess ForArrayBufferBackingStore() { | |
| 74 FieldAccess access = { | |
| 75 kTaggedBase, JSArrayBuffer::kBackingStoreOffset, Handle<Name>(), | |
| 76 Type::UntaggedPtr(), kMachPtr, | |
| 77 }; | |
| 78 return access; | |
| 79 } | |
| 80 | |
| 81 | |
| 82 ElementAccess ForFixedArrayElement() { | |
| 83 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), | |
| 84 kMachAnyTagged}; | |
| 85 return access; | |
| 86 } | |
| 87 | |
| 88 | |
| 89 ElementAccess ForBackingStoreElement(MachineType rep) { | |
| 90 ElementAccess access = {kUntaggedBase, | |
| 91 kNonHeapObjectHeaderSize - kHeapObjectTag, | |
| 92 Type::Any(), rep}; | |
| 93 return access; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 | |
| 98 #ifndef V8_TARGET_ARCH_ARM64 | 57 #ifndef V8_TARGET_ARCH_ARM64 |
| 99 // TODO(titzer): these result in a stub call that doesn't work on ARM64. | 58 // TODO(titzer): these result in a stub call that doesn't work on ARM64. |
| 100 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. | 59 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. |
| 101 // TODO(titzer): test tagged representation for input to NumberToInt32. | 60 // TODO(titzer): test tagged representation for input to NumberToInt32. |
| 102 TEST(RunNumberToInt32_float64) { | 61 TEST(RunNumberToInt32_float64) { |
| 103 // TODO(titzer): explicit load/stores here are only because of representations | 62 // TODO(titzer): explicit load/stores here are only because of representations |
| 104 double input; | 63 double input; |
| 105 int32_t result; | 64 int32_t result; |
| 106 SimplifiedLoweringTester<Object*> t; | 65 SimplifiedLoweringTester<Object*> t; |
| 107 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 66 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 static Handle<JSObject> TestObject() { | 118 static Handle<JSObject> TestObject() { |
| 160 static int index = 0; | 119 static int index = 0; |
| 161 char buffer[50]; | 120 char buffer[50]; |
| 162 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 121 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); |
| 163 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); | 122 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); |
| 164 } | 123 } |
| 165 | 124 |
| 166 | 125 |
| 167 TEST(RunLoadMap) { | 126 TEST(RunLoadMap) { |
| 168 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 127 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| 169 FieldAccess access = ForJSObjectMap(); | 128 FieldAccess access = AccessBuilder::ForMap(); |
| 170 Node* load = t.LoadField(access, t.Parameter(0)); | 129 Node* load = t.LoadField(access, t.Parameter(0)); |
| 171 t.Return(load); | 130 t.Return(load); |
| 172 | 131 |
| 173 t.LowerAllNodes(); | 132 t.LowerAllNodes(); |
| 174 t.GenerateCode(); | 133 t.GenerateCode(); |
| 175 | 134 |
| 176 if (Pipeline::SupportedTarget()) { | 135 if (Pipeline::SupportedTarget()) { |
| 177 Handle<JSObject> src = TestObject(); | 136 Handle<JSObject> src = TestObject(); |
| 178 Handle<Map> src_map(src->map()); | 137 Handle<Map> src_map(src->map()); |
| 179 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 138 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
| 180 CHECK_EQ(*src_map, result); | 139 CHECK_EQ(*src_map, result); |
| 181 } | 140 } |
| 182 } | 141 } |
| 183 | 142 |
| 184 | 143 |
| 185 TEST(RunStoreMap) { | 144 TEST(RunStoreMap) { |
| 186 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); | 145 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); |
| 187 FieldAccess access = ForJSObjectMap(); | 146 FieldAccess access = AccessBuilder::ForMap(); |
| 188 t.StoreField(access, t.Parameter(1), t.Parameter(0)); | 147 t.StoreField(access, t.Parameter(1), t.Parameter(0)); |
| 189 t.Return(t.jsgraph.TrueConstant()); | 148 t.Return(t.jsgraph.TrueConstant()); |
| 190 | 149 |
| 191 t.LowerAllNodes(); | 150 t.LowerAllNodes(); |
| 192 t.GenerateCode(); | 151 t.GenerateCode(); |
| 193 | 152 |
| 194 if (Pipeline::SupportedTarget()) { | 153 if (Pipeline::SupportedTarget()) { |
| 195 Handle<JSObject> src = TestObject(); | 154 Handle<JSObject> src = TestObject(); |
| 196 Handle<Map> src_map(src->map()); | 155 Handle<Map> src_map(src->map()); |
| 197 Handle<JSObject> dst = TestObject(); | 156 Handle<JSObject> dst = TestObject(); |
| 198 CHECK(src->map() != dst->map()); | 157 CHECK(src->map() != dst->map()); |
| 199 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call | 158 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call |
| 200 CHECK(*src_map == dst->map()); | 159 CHECK(*src_map == dst->map()); |
| 201 } | 160 } |
| 202 } | 161 } |
| 203 | 162 |
| 204 | 163 |
| 205 TEST(RunLoadProperties) { | 164 TEST(RunLoadProperties) { |
| 206 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 165 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| 207 FieldAccess access = ForJSObjectProperties(); | 166 FieldAccess access = AccessBuilder::ForJSObjectProperties(); |
| 208 Node* load = t.LoadField(access, t.Parameter(0)); | 167 Node* load = t.LoadField(access, t.Parameter(0)); |
| 209 t.Return(load); | 168 t.Return(load); |
| 210 | 169 |
| 211 t.LowerAllNodes(); | 170 t.LowerAllNodes(); |
| 212 t.GenerateCode(); | 171 t.GenerateCode(); |
| 213 | 172 |
| 214 if (Pipeline::SupportedTarget()) { | 173 if (Pipeline::SupportedTarget()) { |
| 215 Handle<JSObject> src = TestObject(); | 174 Handle<JSObject> src = TestObject(); |
| 216 Handle<FixedArray> src_props(src->properties()); | 175 Handle<FixedArray> src_props(src->properties()); |
| 217 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call | 176 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call |
| 218 CHECK_EQ(*src_props, result); | 177 CHECK_EQ(*src_props, result); |
| 219 } | 178 } |
| 220 } | 179 } |
| 221 | 180 |
| 222 | 181 |
| 223 TEST(RunLoadStoreMap) { | 182 TEST(RunLoadStoreMap) { |
| 224 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); | 183 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); |
| 225 FieldAccess access = ForJSObjectMap(); | 184 FieldAccess access = AccessBuilder::ForMap(); |
| 226 Node* load = t.LoadField(access, t.Parameter(0)); | 185 Node* load = t.LoadField(access, t.Parameter(0)); |
| 227 t.StoreField(access, t.Parameter(1), load); | 186 t.StoreField(access, t.Parameter(1), load); |
| 228 t.Return(load); | 187 t.Return(load); |
| 229 | 188 |
| 230 t.LowerAllNodes(); | 189 t.LowerAllNodes(); |
| 231 t.GenerateCode(); | 190 t.GenerateCode(); |
| 232 | 191 |
| 233 if (Pipeline::SupportedTarget()) { | 192 if (Pipeline::SupportedTarget()) { |
| 234 Handle<JSObject> src = TestObject(); | 193 Handle<JSObject> src = TestObject(); |
| 235 Handle<Map> src_map(src->map()); | 194 Handle<Map> src_map(src->map()); |
| 236 Handle<JSObject> dst = TestObject(); | 195 Handle<JSObject> dst = TestObject(); |
| 237 CHECK(src->map() != dst->map()); | 196 CHECK(src->map() != dst->map()); |
| 238 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call | 197 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call |
| 239 CHECK(result->IsMap()); | 198 CHECK(result->IsMap()); |
| 240 CHECK_EQ(*src_map, result); | 199 CHECK_EQ(*src_map, result); |
| 241 CHECK(*src_map == dst->map()); | 200 CHECK(*src_map == dst->map()); |
| 242 } | 201 } |
| 243 } | 202 } |
| 244 | 203 |
| 245 | 204 |
| 246 TEST(RunLoadStoreFixedArrayIndex) { | 205 TEST(RunLoadStoreFixedArrayIndex) { |
| 247 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 206 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| 248 ElementAccess access = ForFixedArrayElement(); | 207 ElementAccess access = AccessBuilder::ForFixedArrayElement(); |
| 249 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); | 208 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); |
| 250 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); | 209 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); |
| 251 t.Return(load); | 210 t.Return(load); |
| 252 | 211 |
| 253 t.LowerAllNodes(); | 212 t.LowerAllNodes(); |
| 254 t.GenerateCode(); | 213 t.GenerateCode(); |
| 255 | 214 |
| 256 if (Pipeline::SupportedTarget()) { | 215 if (Pipeline::SupportedTarget()) { |
| 257 Handle<FixedArray> array = t.factory()->NewFixedArray(2); | 216 Handle<FixedArray> array = t.factory()->NewFixedArray(2); |
| 258 Handle<JSObject> src = TestObject(); | 217 Handle<JSObject> src = TestObject(); |
| 259 Handle<JSObject> dst = TestObject(); | 218 Handle<JSObject> dst = TestObject(); |
| 260 array->set(0, *src); | 219 array->set(0, *src); |
| 261 array->set(1, *dst); | 220 array->set(1, *dst); |
| 262 Object* result = t.Call(*array); | 221 Object* result = t.Call(*array); |
| 263 CHECK_EQ(*src, result); | 222 CHECK_EQ(*src, result); |
| 264 CHECK_EQ(*src, array->get(0)); | 223 CHECK_EQ(*src, array->get(0)); |
| 265 CHECK_EQ(*src, array->get(1)); | 224 CHECK_EQ(*src, array->get(1)); |
| 266 } | 225 } |
| 267 } | 226 } |
| 268 | 227 |
| 269 | 228 |
| 270 TEST(RunLoadStoreArrayBuffer) { | 229 TEST(RunLoadStoreArrayBuffer) { |
| 271 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); | 230 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); |
| 272 const int index = 12; | 231 const int index = 12; |
| 273 ElementAccess buffer_access = ForBackingStoreElement(kMachInt8); | 232 ElementAccess buffer_access = |
| 274 Node* backing_store = | 233 AccessBuilder::ForBackingStoreElement(kMachInt8); |
| 275 t.LoadField(ForArrayBufferBackingStore(), t.Parameter(0)); | 234 Node* backing_store = t.LoadField( |
| 235 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); |
| 276 Node* load = | 236 Node* load = |
| 277 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); | 237 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); |
| 278 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), | 238 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), |
| 279 load); | 239 load); |
| 280 t.Return(t.jsgraph.TrueConstant()); | 240 t.Return(t.jsgraph.TrueConstant()); |
| 281 | 241 |
| 282 t.LowerAllNodes(); | 242 t.LowerAllNodes(); |
| 283 t.GenerateCode(); | 243 t.GenerateCode(); |
| 284 | 244 |
| 285 if (Pipeline::SupportedTarget()) { | 245 if (Pipeline::SupportedTarget()) { |
| (...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 | 1408 |
| 1449 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1409 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
| 1450 t.p1, t.start, t.start); | 1410 t.p1, t.start, t.start); |
| 1451 t.Effect(store); | 1411 t.Effect(store); |
| 1452 t.Lower(); | 1412 t.Lower(); |
| 1453 | 1413 |
| 1454 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1414 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
| 1455 CHECK_EQ(t.p0, store->InputAt(0)); | 1415 CHECK_EQ(t.p0, store->InputAt(0)); |
| 1456 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1416 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
| 1457 } | 1417 } |
| OLD | NEW |