 Chromium Code Reviews
 Chromium Code Reviews Issue 2557283002:
  [turbofan] Add NewUnmappedArgumentsElements and NewRestParametersArguments.  (Closed)
    
  
    Issue 2557283002:
  [turbofan] Add NewUnmappedArgumentsElements and NewRestParametersArguments.  (Closed) 
  | 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); | |
| 
Jarin
2016/12/08 07:49:22
STATIC_ASSERT -> static_assert (here and below).
 
Benedikt Meurer
2016/12/08 07:58:15
I think we continue using our STATIC_ASSERT. We sh
 | |
| 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 |