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 "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 rglobal, control); | 1309 rglobal, control); |
1310 } | 1310 } |
1311 } | 1311 } |
1312 ReplaceWithValue(node, receiver, effect, control); | 1312 ReplaceWithValue(node, receiver, effect, control); |
1313 return Changed(receiver); | 1313 return Changed(receiver); |
1314 } | 1314 } |
1315 | 1315 |
1316 | 1316 |
1317 namespace { | 1317 namespace { |
1318 | 1318 |
| 1319 // Maximum instance size for which allocations will be inlined. |
| 1320 const int kMaxInlineInstanceSize = 64 * kPointerSize; |
| 1321 |
| 1322 |
| 1323 // Checks whether allocation using the given constructor can be inlined. |
| 1324 bool IsAllocationInlineable(Handle<JSFunction> constructor) { |
| 1325 // TODO(bmeurer): Support inlining of class constructors. |
| 1326 if (IsClassConstructor(constructor->shared()->kind())) return false; |
| 1327 return constructor->has_initial_map() && |
| 1328 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && |
| 1329 constructor->initial_map()->instance_size() < kMaxInlineInstanceSize; |
| 1330 } |
| 1331 |
| 1332 } // namespace |
| 1333 |
| 1334 |
| 1335 Reduction JSTypedLowering::ReduceJSCreate(Node* node) { |
| 1336 DCHECK_EQ(IrOpcode::kJSCreate, node->opcode()); |
| 1337 Node* const target = NodeProperties::GetValueInput(node, 0); |
| 1338 Type* const target_type = NodeProperties::GetType(target); |
| 1339 Node* const new_target = NodeProperties::GetValueInput(node, 1); |
| 1340 Node* const effect = NodeProperties::GetEffectInput(node); |
| 1341 // TODO(turbofan): Add support for NewTarget passed to JSCreate. |
| 1342 if (target != new_target) return NoChange(); |
| 1343 // Extract constructor function. |
| 1344 if (target_type->IsConstant() && |
| 1345 target_type->AsConstant()->Value()->IsJSFunction()) { |
| 1346 Handle<JSFunction> constructor = |
| 1347 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); |
| 1348 // Force completion of inobject slack tracking before |
| 1349 // generating code to finalize the instance size. |
| 1350 if (constructor->IsInobjectSlackTrackingInProgress()) { |
| 1351 constructor->CompleteInobjectSlackTracking(); |
| 1352 } |
| 1353 |
| 1354 // TODO(bmeurer): We fall back to the runtime in case we cannot inline |
| 1355 // the allocation here, which is sort of expensive. We should think about |
| 1356 // a soft fallback to some NewObjectCodeStub. |
| 1357 if (IsAllocationInlineable(constructor)) { |
| 1358 // Compute instance size from initial map of {constructor}. |
| 1359 Handle<Map> initial_map(constructor->initial_map(), isolate()); |
| 1360 int const instance_size = initial_map->instance_size(); |
| 1361 |
| 1362 // Add a dependency on the {initial_map} to make sure that this code is |
| 1363 // deoptimized whenever the {initial_map} of the {constructor} changes. |
| 1364 dependencies()->AssumeInitialMapCantChange(initial_map); |
| 1365 |
| 1366 // Emit code to allocate the JSObject instance for the {constructor}. |
| 1367 AllocationBuilder a(jsgraph(), effect, graph()->start()); |
| 1368 a.Allocate(instance_size); |
| 1369 a.Store(AccessBuilder::ForMap(), initial_map); |
| 1370 a.Store(AccessBuilder::ForJSObjectProperties(), |
| 1371 jsgraph()->EmptyFixedArrayConstant()); |
| 1372 a.Store(AccessBuilder::ForJSObjectElements(), |
| 1373 jsgraph()->EmptyFixedArrayConstant()); |
| 1374 for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) { |
| 1375 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i), |
| 1376 jsgraph()->UndefinedConstant()); |
| 1377 } |
| 1378 a.FinishAndChange(node); |
| 1379 return Changed(node); |
| 1380 } |
| 1381 } |
| 1382 return NoChange(); |
| 1383 } |
| 1384 |
| 1385 |
| 1386 namespace { |
| 1387 |
1319 // Retrieves the frame state holding actual argument values. | 1388 // Retrieves the frame state holding actual argument values. |
1320 Node* GetArgumentsFrameState(Node* frame_state) { | 1389 Node* GetArgumentsFrameState(Node* frame_state) { |
1321 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); | 1390 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); |
1322 FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state); | 1391 FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state); |
1323 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor | 1392 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor |
1324 ? outer_state | 1393 ? outer_state |
1325 : frame_state; | 1394 : frame_state; |
1326 } | 1395 } |
1327 | 1396 |
1328 } // namespace | 1397 } // namespace |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 case IrOpcode::kJSStoreProperty: | 2215 case IrOpcode::kJSStoreProperty: |
2147 return ReduceJSStoreProperty(node); | 2216 return ReduceJSStoreProperty(node); |
2148 case IrOpcode::kJSInstanceOf: | 2217 case IrOpcode::kJSInstanceOf: |
2149 return ReduceJSInstanceOf(node); | 2218 return ReduceJSInstanceOf(node); |
2150 case IrOpcode::kJSLoadContext: | 2219 case IrOpcode::kJSLoadContext: |
2151 return ReduceJSLoadContext(node); | 2220 return ReduceJSLoadContext(node); |
2152 case IrOpcode::kJSStoreContext: | 2221 case IrOpcode::kJSStoreContext: |
2153 return ReduceJSStoreContext(node); | 2222 return ReduceJSStoreContext(node); |
2154 case IrOpcode::kJSConvertReceiver: | 2223 case IrOpcode::kJSConvertReceiver: |
2155 return ReduceJSConvertReceiver(node); | 2224 return ReduceJSConvertReceiver(node); |
| 2225 case IrOpcode::kJSCreate: |
| 2226 return ReduceJSCreate(node); |
2156 case IrOpcode::kJSCreateArguments: | 2227 case IrOpcode::kJSCreateArguments: |
2157 return ReduceJSCreateArguments(node); | 2228 return ReduceJSCreateArguments(node); |
2158 case IrOpcode::kJSCreateClosure: | 2229 case IrOpcode::kJSCreateClosure: |
2159 return ReduceJSCreateClosure(node); | 2230 return ReduceJSCreateClosure(node); |
2160 case IrOpcode::kJSCreateLiteralArray: | 2231 case IrOpcode::kJSCreateLiteralArray: |
2161 return ReduceJSCreateLiteralArray(node); | 2232 return ReduceJSCreateLiteralArray(node); |
2162 case IrOpcode::kJSCreateLiteralObject: | 2233 case IrOpcode::kJSCreateLiteralObject: |
2163 return ReduceJSCreateLiteralObject(node); | 2234 return ReduceJSCreateLiteralObject(node); |
2164 case IrOpcode::kJSCreateFunctionContext: | 2235 case IrOpcode::kJSCreateFunctionContext: |
2165 return ReduceJSCreateFunctionContext(node); | 2236 return ReduceJSCreateFunctionContext(node); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2295 } | 2366 } |
2296 | 2367 |
2297 | 2368 |
2298 CompilationDependencies* JSTypedLowering::dependencies() const { | 2369 CompilationDependencies* JSTypedLowering::dependencies() const { |
2299 return dependencies_; | 2370 return dependencies_; |
2300 } | 2371 } |
2301 | 2372 |
2302 } // namespace compiler | 2373 } // namespace compiler |
2303 } // namespace internal | 2374 } // namespace internal |
2304 } // namespace v8 | 2375 } // namespace v8 |
OLD | NEW |