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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 // arguments objects, so that we always have a shared_info here. | 302 // arguments objects, so that we always have a shared_info here. |
303 Handle<SharedFunctionInfo> shared_info; | 303 Handle<SharedFunctionInfo> shared_info; |
304 if (state_info.shared_info().ToHandle(&shared_info)) { | 304 if (state_info.shared_info().ToHandle(&shared_info)) { |
305 // TODO(mstarzinger): Duplicate parameters are not handled yet. | 305 // TODO(mstarzinger): Duplicate parameters are not handled yet. |
306 if (shared_info->has_duplicate_parameters()) return NoChange(); | 306 if (shared_info->has_duplicate_parameters()) return NoChange(); |
307 // If there is no aliasing, the arguments object elements are not | 307 // If there is no aliasing, the arguments object elements are not |
308 // special in any way, we can just return an unmapped backing store. | 308 // special in any way, we can just return an unmapped backing store. |
309 if (shared_info->internal_formal_parameter_count() == 0) { | 309 if (shared_info->internal_formal_parameter_count() == 0) { |
310 Node* const callee = NodeProperties::GetValueInput(node, 0); | 310 Node* const callee = NodeProperties::GetValueInput(node, 0); |
311 Node* effect = NodeProperties::GetEffectInput(node); | 311 Node* effect = NodeProperties::GetEffectInput(node); |
| 312 Node* const arguments_frame = |
| 313 graph()->NewNode(simplified()->ArgumentsFrame()); |
| 314 Node* const arguments_length = graph()->NewNode( |
| 315 simplified()->ArgumentsLength(0, false), arguments_frame); |
312 // Allocate the elements backing store. | 316 // Allocate the elements backing store. |
313 Node* const elements = effect = graph()->NewNode( | 317 Node* const elements = effect = |
314 simplified()->NewUnmappedArgumentsElements(0), effect); | 318 graph()->NewNode(simplified()->NewUnmappedArgumentsElements(), |
315 Node* const length = effect = graph()->NewNode( | 319 arguments_frame, arguments_length, effect); |
316 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), | |
317 elements, effect, control); | |
318 // Load the arguments object map. | 320 // Load the arguments object map. |
319 Node* const arguments_map = jsgraph()->HeapConstant( | 321 Node* const arguments_map = jsgraph()->HeapConstant( |
320 handle(native_context()->sloppy_arguments_map(), isolate())); | 322 handle(native_context()->sloppy_arguments_map(), isolate())); |
321 // Actually allocate and initialize the arguments object. | 323 // Actually allocate and initialize the arguments object. |
322 AllocationBuilder a(jsgraph(), effect, control); | 324 AllocationBuilder a(jsgraph(), effect, control); |
323 Node* properties = jsgraph()->EmptyFixedArrayConstant(); | 325 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
324 STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize); | 326 STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize); |
325 a.Allocate(JSSloppyArgumentsObject::kSize); | 327 a.Allocate(JSSloppyArgumentsObject::kSize); |
326 a.Store(AccessBuilder::ForMap(), arguments_map); | 328 a.Store(AccessBuilder::ForMap(), arguments_map); |
327 a.Store(AccessBuilder::ForJSObjectProperties(), properties); | 329 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
328 a.Store(AccessBuilder::ForJSObjectElements(), elements); | 330 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
329 a.Store(AccessBuilder::ForArgumentsLength(), length); | 331 a.Store(AccessBuilder::ForArgumentsLength(), arguments_length); |
330 a.Store(AccessBuilder::ForArgumentsCallee(), callee); | 332 a.Store(AccessBuilder::ForArgumentsCallee(), callee); |
331 RelaxControls(node); | 333 RelaxControls(node); |
332 a.FinishAndChange(node); | 334 a.FinishAndChange(node); |
333 } else { | 335 } else { |
334 Callable callable = CodeFactory::FastNewSloppyArguments(isolate()); | 336 Callable callable = CodeFactory::FastNewSloppyArguments(isolate()); |
335 Operator::Properties properties = node->op()->properties(); | 337 Operator::Properties properties = node->op()->properties(); |
336 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 338 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
337 isolate(), graph()->zone(), callable.descriptor(), 0, | 339 isolate(), graph()->zone(), callable.descriptor(), 0, |
338 CallDescriptor::kNoFlags, properties); | 340 CallDescriptor::kNoFlags, properties); |
339 const Operator* new_op = common()->Call(desc); | 341 const Operator* new_op = common()->Call(desc); |
340 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 342 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
341 node->InsertInput(graph()->zone(), 0, stub_code); | 343 node->InsertInput(graph()->zone(), 0, stub_code); |
342 node->RemoveInput(3); // Remove the frame state. | 344 node->RemoveInput(3); // Remove the frame state. |
343 NodeProperties::ChangeOp(node, new_op); | 345 NodeProperties::ChangeOp(node, new_op); |
344 } | 346 } |
345 return Changed(node); | 347 return Changed(node); |
346 } | 348 } |
347 return NoChange(); | 349 return NoChange(); |
348 } | 350 } |
349 case CreateArgumentsType::kUnmappedArguments: { | 351 case CreateArgumentsType::kUnmappedArguments: { |
350 Handle<SharedFunctionInfo> shared_info; | 352 Handle<SharedFunctionInfo> shared_info; |
351 if (state_info.shared_info().ToHandle(&shared_info)) { | 353 if (state_info.shared_info().ToHandle(&shared_info)) { |
352 Node* effect = NodeProperties::GetEffectInput(node); | 354 Node* effect = NodeProperties::GetEffectInput(node); |
| 355 Node* const arguments_frame = |
| 356 graph()->NewNode(simplified()->ArgumentsFrame()); |
| 357 Node* const arguments_length = graph()->NewNode( |
| 358 simplified()->ArgumentsLength( |
| 359 shared_info->internal_formal_parameter_count(), false), |
| 360 arguments_frame); |
353 // Allocate the elements backing store. | 361 // Allocate the elements backing store. |
354 Node* const elements = effect = graph()->NewNode( | 362 Node* const elements = effect = |
355 simplified()->NewUnmappedArgumentsElements( | 363 graph()->NewNode(simplified()->NewUnmappedArgumentsElements(), |
356 shared_info->internal_formal_parameter_count()), | 364 arguments_frame, arguments_length, effect); |
357 effect); | |
358 Node* const length = effect = graph()->NewNode( | |
359 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), | |
360 elements, effect, control); | |
361 // Load the arguments object map. | 365 // Load the arguments object map. |
362 Node* const arguments_map = jsgraph()->HeapConstant( | 366 Node* const arguments_map = jsgraph()->HeapConstant( |
363 handle(native_context()->strict_arguments_map(), isolate())); | 367 handle(native_context()->strict_arguments_map(), isolate())); |
364 // Actually allocate and initialize the arguments object. | 368 // Actually allocate and initialize the arguments object. |
365 AllocationBuilder a(jsgraph(), effect, control); | 369 AllocationBuilder a(jsgraph(), effect, control); |
366 Node* properties = jsgraph()->EmptyFixedArrayConstant(); | 370 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
367 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); | 371 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); |
368 a.Allocate(JSStrictArgumentsObject::kSize); | 372 a.Allocate(JSStrictArgumentsObject::kSize); |
369 a.Store(AccessBuilder::ForMap(), arguments_map); | 373 a.Store(AccessBuilder::ForMap(), arguments_map); |
370 a.Store(AccessBuilder::ForJSObjectProperties(), properties); | 374 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
371 a.Store(AccessBuilder::ForJSObjectElements(), elements); | 375 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
372 a.Store(AccessBuilder::ForArgumentsLength(), length); | 376 a.Store(AccessBuilder::ForArgumentsLength(), arguments_length); |
373 RelaxControls(node); | 377 RelaxControls(node); |
374 a.FinishAndChange(node); | 378 a.FinishAndChange(node); |
375 } else { | 379 } else { |
376 Callable callable = CodeFactory::FastNewStrictArguments(isolate()); | 380 Callable callable = CodeFactory::FastNewStrictArguments(isolate()); |
377 Operator::Properties properties = node->op()->properties(); | 381 Operator::Properties properties = node->op()->properties(); |
378 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 382 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
379 isolate(), graph()->zone(), callable.descriptor(), 0, | 383 isolate(), graph()->zone(), callable.descriptor(), 0, |
380 CallDescriptor::kNeedsFrameState, properties); | 384 CallDescriptor::kNeedsFrameState, properties); |
381 const Operator* new_op = common()->Call(desc); | 385 const Operator* new_op = common()->Call(desc); |
382 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 386 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
383 node->InsertInput(graph()->zone(), 0, stub_code); | 387 node->InsertInput(graph()->zone(), 0, stub_code); |
384 NodeProperties::ChangeOp(node, new_op); | 388 NodeProperties::ChangeOp(node, new_op); |
385 } | 389 } |
386 return Changed(node); | 390 return Changed(node); |
387 } | 391 } |
388 case CreateArgumentsType::kRestParameter: { | 392 case CreateArgumentsType::kRestParameter: { |
389 Handle<SharedFunctionInfo> shared_info; | 393 Handle<SharedFunctionInfo> shared_info; |
390 if (state_info.shared_info().ToHandle(&shared_info)) { | 394 if (state_info.shared_info().ToHandle(&shared_info)) { |
391 Node* effect = NodeProperties::GetEffectInput(node); | 395 Node* effect = NodeProperties::GetEffectInput(node); |
392 // Allocate the elements backing store. | 396 Node* const arguments_frame = |
393 Node* const elements = effect = graph()->NewNode( | 397 graph()->NewNode(simplified()->ArgumentsFrame()); |
394 simplified()->NewRestParameterElements( | 398 int formal_parameter_count = |
395 shared_info->internal_formal_parameter_count()), | 399 shared_info->internal_formal_parameter_count(); |
396 effect); | 400 Node* const rest_length = graph()->NewNode( |
397 Node* const length = effect = graph()->NewNode( | 401 simplified()->ArgumentsLength(formal_parameter_count, true), |
398 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), | 402 arguments_frame); |
399 elements, effect, control); | 403 // Allocate the elements backing store. Since |
| 404 // NewUnmappedArgumentsElements copies from the end of the arguments |
| 405 // adapter frame, this is a suffix of the actual arguments. |
| 406 Node* const elements = effect = |
| 407 graph()->NewNode(simplified()->NewUnmappedArgumentsElements(), |
| 408 arguments_frame, rest_length, effect); |
400 // Load the JSArray object map. | 409 // Load the JSArray object map. |
401 Node* const jsarray_map = jsgraph()->HeapConstant(handle( | 410 Node* const jsarray_map = jsgraph()->HeapConstant(handle( |
402 native_context()->js_array_fast_elements_map_index(), isolate())); | 411 native_context()->js_array_fast_elements_map_index(), isolate())); |
403 // Actually allocate and initialize the jsarray. | 412 // Actually allocate and initialize the jsarray. |
404 AllocationBuilder a(jsgraph(), effect, control); | 413 AllocationBuilder a(jsgraph(), effect, control); |
405 Node* properties = jsgraph()->EmptyFixedArrayConstant(); | 414 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
406 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); | 415 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
407 a.Allocate(JSArray::kSize); | 416 a.Allocate(JSArray::kSize); |
408 a.Store(AccessBuilder::ForMap(), jsarray_map); | 417 a.Store(AccessBuilder::ForMap(), jsarray_map); |
409 a.Store(AccessBuilder::ForJSObjectProperties(), properties); | 418 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
410 a.Store(AccessBuilder::ForJSObjectElements(), elements); | 419 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
411 a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), length); | 420 a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), rest_length); |
412 RelaxControls(node); | 421 RelaxControls(node); |
413 a.FinishAndChange(node); | 422 a.FinishAndChange(node); |
414 } else { | 423 } else { |
415 Callable callable = CodeFactory::FastNewRestParameter(isolate()); | 424 Callable callable = CodeFactory::FastNewRestParameter(isolate()); |
416 Operator::Properties properties = node->op()->properties(); | 425 Operator::Properties properties = node->op()->properties(); |
417 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 426 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
418 isolate(), graph()->zone(), callable.descriptor(), 0, | 427 isolate(), graph()->zone(), callable.descriptor(), 0, |
419 CallDescriptor::kNeedsFrameState, properties); | 428 CallDescriptor::kNeedsFrameState, properties); |
420 const Operator* new_op = common()->Call(desc); | 429 const Operator* new_op = common()->Call(desc); |
421 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 430 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 return jsgraph()->simplified(); | 1356 return jsgraph()->simplified(); |
1348 } | 1357 } |
1349 | 1358 |
1350 MachineOperatorBuilder* JSCreateLowering::machine() const { | 1359 MachineOperatorBuilder* JSCreateLowering::machine() const { |
1351 return jsgraph()->machine(); | 1360 return jsgraph()->machine(); |
1352 } | 1361 } |
1353 | 1362 |
1354 } // namespace compiler | 1363 } // namespace compiler |
1355 } // namespace internal | 1364 } // namespace internal |
1356 } // namespace v8 | 1365 } // namespace v8 |
OLD | NEW |