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