OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/compiler/js-create-lowering.h" | 5 #include "src/compiler/js-create-lowering.h" |
6 | 6 |
7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 Node* const frame_state = NodeProperties::GetFrameStateInput(node); | 288 Node* const frame_state = NodeProperties::GetFrameStateInput(node); |
289 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); | 289 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); |
290 Node* const control = graph()->start(); | 290 Node* const control = graph()->start(); |
291 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 291 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
292 | 292 |
293 // Use the ArgumentsAccessStub for materializing both mapped and unmapped | 293 // Use the ArgumentsAccessStub for materializing both mapped and unmapped |
294 // arguments object, but only for non-inlined (i.e. outermost) frames. | 294 // arguments object, but only for non-inlined (i.e. outermost) frames. |
295 if (outer_state->opcode() != IrOpcode::kFrameState) { | 295 if (outer_state->opcode() != IrOpcode::kFrameState) { |
296 switch (type) { | 296 switch (type) { |
297 case CreateArgumentsType::kMappedArguments: { | 297 case CreateArgumentsType::kMappedArguments: { |
298 // TODO(mstarzinger): Duplicate parameters are not handled yet. | 298 // TODO(bmeurer): Make deoptimization mandatory for the various |
| 299 // arguments objects, so that we always have a shared_info here. |
299 Handle<SharedFunctionInfo> shared_info; | 300 Handle<SharedFunctionInfo> shared_info; |
300 if (!state_info.shared_info().ToHandle(&shared_info) || | 301 if (state_info.shared_info().ToHandle(&shared_info)) { |
301 shared_info->has_duplicate_parameters()) { | 302 // TODO(mstarzinger): Duplicate parameters are not handled yet. |
302 return NoChange(); | 303 if (shared_info->has_duplicate_parameters()) return NoChange(); |
| 304 // If there is no aliasing, the arguments object elements are not |
| 305 // special in any way, we can just return an unmapped backing store. |
| 306 if (shared_info->internal_formal_parameter_count() == 0) { |
| 307 Node* const callee = NodeProperties::GetValueInput(node, 0); |
| 308 Node* effect = NodeProperties::GetEffectInput(node); |
| 309 // Allocate the elements backing store. |
| 310 Node* const elements = effect = graph()->NewNode( |
| 311 simplified()->NewUnmappedArgumentsElements(0), effect); |
| 312 Node* const length = effect = graph()->NewNode( |
| 313 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
| 314 elements, effect, control); |
| 315 // Load the arguments object map. |
| 316 Node* const arguments_map = jsgraph()->HeapConstant( |
| 317 handle(native_context()->sloppy_arguments_map(), isolate())); |
| 318 // Actually allocate and initialize the arguments object. |
| 319 AllocationBuilder a(jsgraph(), effect, control); |
| 320 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
| 321 STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize); |
| 322 a.Allocate(JSSloppyArgumentsObject::kSize); |
| 323 a.Store(AccessBuilder::ForMap(), arguments_map); |
| 324 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 325 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 326 a.Store(AccessBuilder::ForArgumentsLength(), length); |
| 327 a.Store(AccessBuilder::ForArgumentsCallee(), callee); |
| 328 RelaxControls(node); |
| 329 a.FinishAndChange(node); |
| 330 } else { |
| 331 Callable callable = CodeFactory::FastNewSloppyArguments(isolate()); |
| 332 Operator::Properties properties = node->op()->properties(); |
| 333 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 334 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 335 CallDescriptor::kNoFlags, properties); |
| 336 const Operator* new_op = common()->Call(desc); |
| 337 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 338 node->InsertInput(graph()->zone(), 0, stub_code); |
| 339 node->RemoveInput(3); // Remove the frame state. |
| 340 NodeProperties::ChangeOp(node, new_op); |
| 341 } |
| 342 return Changed(node); |
303 } | 343 } |
304 Callable callable = CodeFactory::FastNewSloppyArguments(isolate()); | 344 return NoChange(); |
305 Operator::Properties properties = node->op()->properties(); | |
306 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
307 isolate(), graph()->zone(), callable.descriptor(), 0, | |
308 CallDescriptor::kNoFlags, properties); | |
309 const Operator* new_op = common()->Call(desc); | |
310 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | |
311 node->InsertInput(graph()->zone(), 0, stub_code); | |
312 node->RemoveInput(3); // Remove the frame state. | |
313 NodeProperties::ChangeOp(node, new_op); | |
314 return Changed(node); | |
315 } | 345 } |
316 case CreateArgumentsType::kUnmappedArguments: { | 346 case CreateArgumentsType::kUnmappedArguments: { |
317 Callable callable = CodeFactory::FastNewStrictArguments(isolate()); | 347 Handle<SharedFunctionInfo> shared_info; |
318 Operator::Properties properties = node->op()->properties(); | 348 if (state_info.shared_info().ToHandle(&shared_info)) { |
319 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 349 Node* effect = NodeProperties::GetEffectInput(node); |
320 isolate(), graph()->zone(), callable.descriptor(), 0, | 350 // Allocate the elements backing store. |
321 CallDescriptor::kNeedsFrameState, properties); | 351 Node* const elements = effect = graph()->NewNode( |
322 const Operator* new_op = common()->Call(desc); | 352 simplified()->NewUnmappedArgumentsElements( |
323 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 353 shared_info->internal_formal_parameter_count()), |
324 node->InsertInput(graph()->zone(), 0, stub_code); | 354 effect); |
325 NodeProperties::ChangeOp(node, new_op); | 355 Node* const length = effect = graph()->NewNode( |
| 356 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
| 357 elements, effect, control); |
| 358 // Load the arguments object map. |
| 359 Node* const arguments_map = jsgraph()->HeapConstant( |
| 360 handle(native_context()->strict_arguments_map(), isolate())); |
| 361 // Actually allocate and initialize the arguments object. |
| 362 AllocationBuilder a(jsgraph(), effect, control); |
| 363 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
| 364 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); |
| 365 a.Allocate(JSStrictArgumentsObject::kSize); |
| 366 a.Store(AccessBuilder::ForMap(), arguments_map); |
| 367 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 368 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 369 a.Store(AccessBuilder::ForArgumentsLength(), length); |
| 370 RelaxControls(node); |
| 371 a.FinishAndChange(node); |
| 372 } else { |
| 373 Callable callable = CodeFactory::FastNewStrictArguments(isolate()); |
| 374 Operator::Properties properties = node->op()->properties(); |
| 375 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 376 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 377 CallDescriptor::kNeedsFrameState, properties); |
| 378 const Operator* new_op = common()->Call(desc); |
| 379 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 380 node->InsertInput(graph()->zone(), 0, stub_code); |
| 381 NodeProperties::ChangeOp(node, new_op); |
| 382 } |
326 return Changed(node); | 383 return Changed(node); |
327 } | 384 } |
328 case CreateArgumentsType::kRestParameter: { | 385 case CreateArgumentsType::kRestParameter: { |
329 Callable callable = CodeFactory::FastNewRestParameter(isolate()); | 386 Handle<SharedFunctionInfo> shared_info; |
330 Operator::Properties properties = node->op()->properties(); | 387 if (state_info.shared_info().ToHandle(&shared_info)) { |
331 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 388 Node* effect = NodeProperties::GetEffectInput(node); |
332 isolate(), graph()->zone(), callable.descriptor(), 0, | 389 // Allocate the elements backing store. |
333 CallDescriptor::kNeedsFrameState, properties); | 390 Node* const elements = effect = graph()->NewNode( |
334 const Operator* new_op = common()->Call(desc); | 391 simplified()->NewRestParameterElements( |
335 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 392 shared_info->internal_formal_parameter_count()), |
336 node->InsertInput(graph()->zone(), 0, stub_code); | 393 effect); |
337 NodeProperties::ChangeOp(node, new_op); | 394 Node* const length = effect = graph()->NewNode( |
| 395 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
| 396 elements, effect, control); |
| 397 // Load the JSArray object map. |
| 398 Node* const jsarray_map = jsgraph()->HeapConstant(handle( |
| 399 native_context()->js_array_fast_elements_map_index(), isolate())); |
| 400 // Actually allocate and initialize the jsarray. |
| 401 AllocationBuilder a(jsgraph(), effect, control); |
| 402 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
| 403 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 404 a.Allocate(JSArray::kSize); |
| 405 a.Store(AccessBuilder::ForMap(), jsarray_map); |
| 406 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 407 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 408 a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), length); |
| 409 RelaxControls(node); |
| 410 a.FinishAndChange(node); |
| 411 } else { |
| 412 Callable callable = CodeFactory::FastNewRestParameter(isolate()); |
| 413 Operator::Properties properties = node->op()->properties(); |
| 414 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 415 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 416 CallDescriptor::kNeedsFrameState, properties); |
| 417 const Operator* new_op = common()->Call(desc); |
| 418 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 419 node->InsertInput(graph()->zone(), 0, stub_code); |
| 420 NodeProperties::ChangeOp(node, new_op); |
| 421 } |
338 return Changed(node); | 422 return Changed(node); |
339 } | 423 } |
340 } | 424 } |
341 UNREACHABLE(); | 425 UNREACHABLE(); |
342 } else if (outer_state->opcode() == IrOpcode::kFrameState) { | 426 } else if (outer_state->opcode() == IrOpcode::kFrameState) { |
343 // Use inline allocation for all mapped arguments objects within inlined | 427 // Use inline allocation for all mapped arguments objects within inlined |
344 // (i.e. non-outermost) frames, independent of the object size. | 428 // (i.e. non-outermost) frames, independent of the object size. |
345 if (type == CreateArgumentsType::kMappedArguments) { | 429 if (type == CreateArgumentsType::kMappedArguments) { |
346 Handle<SharedFunctionInfo> shared; | 430 Handle<SharedFunctionInfo> shared; |
347 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); | 431 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); |
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 return jsgraph()->simplified(); | 1361 return jsgraph()->simplified(); |
1278 } | 1362 } |
1279 | 1363 |
1280 MachineOperatorBuilder* JSCreateLowering::machine() const { | 1364 MachineOperatorBuilder* JSCreateLowering::machine() const { |
1281 return jsgraph()->machine(); | 1365 return jsgraph()->machine(); |
1282 } | 1366 } |
1283 | 1367 |
1284 } // namespace compiler | 1368 } // namespace compiler |
1285 } // namespace internal | 1369 } // namespace internal |
1286 } // namespace v8 | 1370 } // namespace v8 |
OLD | NEW |