| 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/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
| 9 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
| 10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { | 205 Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { |
| 206 DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode()); | 206 DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode()); |
| 207 CreateArgumentsType type = CreateArgumentsTypeOf(node->op()); | 207 CreateArgumentsType type = CreateArgumentsTypeOf(node->op()); |
| 208 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0); | 208 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 209 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); | 209 Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput); |
| 210 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 210 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
| 211 | 211 |
| 212 // Use the ArgumentsAccessStub for materializing both mapped and unmapped | 212 // Use the ArgumentsAccessStub for materializing both mapped and unmapped |
| 213 // arguments object, but only for non-inlined (i.e. outermost) frames. | 213 // arguments object, but only for non-inlined (i.e. outermost) frames. |
| 214 if (outer_state->opcode() != IrOpcode::kFrameState) { | 214 if (outer_state->opcode() != IrOpcode::kFrameState) { |
| 215 if (type != CreateArgumentsType::kRestParameter) { | 215 switch (type) { |
| 216 // TODO(bmeurer): Cleanup this mess at some point. | 216 case CreateArgumentsType::kMappedArguments: { |
| 217 int parameter_count = state_info.parameter_count() - 1; | 217 // TODO(bmeurer): Cleanup this mess at some point. |
| 218 int parameter_offset = parameter_count * kPointerSize; | 218 int parameter_count = state_info.parameter_count() - 1; |
| 219 int offset = StandardFrameConstants::kCallerSPOffset + parameter_offset; | 219 int parameter_offset = parameter_count * kPointerSize; |
| 220 Node* parameter_pointer = graph()->NewNode( | 220 int offset = StandardFrameConstants::kCallerSPOffset + parameter_offset; |
| 221 machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()), | 221 Node* parameter_pointer = |
| 222 jsgraph()->IntPtrConstant(offset)); | 222 graph()->NewNode(machine()->IntAdd(), |
| 223 Handle<SharedFunctionInfo> shared; | 223 graph()->NewNode(machine()->LoadFramePointer()), |
| 224 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); | 224 jsgraph()->IntPtrConstant(offset)); |
| 225 bool unmapped = type == CreateArgumentsType::kUnmappedArguments; | 225 Handle<SharedFunctionInfo> shared; |
| 226 Callable callable = CodeFactory::ArgumentsAccess( | 226 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); |
| 227 isolate(), unmapped, shared->has_duplicate_parameters()); | 227 Callable callable = CodeFactory::ArgumentsAccess( |
| 228 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 228 isolate(), shared->has_duplicate_parameters()); |
| 229 isolate(), graph()->zone(), callable.descriptor(), 0, | 229 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 230 CallDescriptor::kNeedsFrameState); | 230 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 231 const Operator* new_op = common()->Call(desc); | 231 CallDescriptor::kNeedsFrameState); |
| 232 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 232 const Operator* new_op = common()->Call(desc); |
| 233 node->InsertInput(graph()->zone(), 0, stub_code); | 233 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 234 node->InsertInput(graph()->zone(), 2, | 234 node->InsertInput(graph()->zone(), 0, stub_code); |
| 235 jsgraph()->Constant(parameter_count)); | 235 node->InsertInput(graph()->zone(), 2, |
| 236 node->InsertInput(graph()->zone(), 3, parameter_pointer); | 236 jsgraph()->Constant(parameter_count)); |
| 237 NodeProperties::ChangeOp(node, new_op); | 237 node->InsertInput(graph()->zone(), 3, parameter_pointer); |
| 238 return Changed(node); | 238 NodeProperties::ChangeOp(node, new_op); |
| 239 } else { | 239 return Changed(node); |
| 240 Callable callable = CodeFactory::FastNewRestParameter(isolate()); | 240 } |
| 241 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 241 case CreateArgumentsType::kUnmappedArguments: { |
| 242 isolate(), graph()->zone(), callable.descriptor(), 0, | 242 Callable callable = CodeFactory::FastNewStrictArguments(isolate()); |
| 243 CallDescriptor::kNeedsFrameState); | 243 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 244 const Operator* new_op = common()->Call(desc); | 244 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 245 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 245 CallDescriptor::kNeedsFrameState); |
| 246 node->InsertInput(graph()->zone(), 0, stub_code); | 246 const Operator* new_op = common()->Call(desc); |
| 247 NodeProperties::ChangeOp(node, new_op); | 247 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 248 return Changed(node); | 248 node->InsertInput(graph()->zone(), 0, stub_code); |
| 249 NodeProperties::ChangeOp(node, new_op); |
| 250 return Changed(node); |
| 251 } |
| 252 case CreateArgumentsType::kRestParameter: { |
| 253 Callable callable = CodeFactory::FastNewRestParameter(isolate()); |
| 254 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 255 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 256 CallDescriptor::kNeedsFrameState); |
| 257 const Operator* new_op = common()->Call(desc); |
| 258 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 259 node->InsertInput(graph()->zone(), 0, stub_code); |
| 260 NodeProperties::ChangeOp(node, new_op); |
| 261 return Changed(node); |
| 262 } |
| 249 } | 263 } |
| 264 UNREACHABLE(); |
| 250 } else if (outer_state->opcode() == IrOpcode::kFrameState) { | 265 } else if (outer_state->opcode() == IrOpcode::kFrameState) { |
| 251 // Use inline allocation for all mapped arguments objects within inlined | 266 // Use inline allocation for all mapped arguments objects within inlined |
| 252 // (i.e. non-outermost) frames, independent of the object size. | 267 // (i.e. non-outermost) frames, independent of the object size. |
| 253 if (type == CreateArgumentsType::kMappedArguments) { | 268 if (type == CreateArgumentsType::kMappedArguments) { |
| 254 Handle<SharedFunctionInfo> shared; | 269 Handle<SharedFunctionInfo> shared; |
| 255 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); | 270 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); |
| 256 Node* const callee = NodeProperties::GetValueInput(node, 0); | 271 Node* const callee = NodeProperties::GetValueInput(node, 0); |
| 257 Node* const control = NodeProperties::GetControlInput(node); | 272 Node* const control = NodeProperties::GetControlInput(node); |
| 258 Node* const context = NodeProperties::GetContextInput(node); | 273 Node* const context = NodeProperties::GetContextInput(node); |
| 259 Node* effect = NodeProperties::GetEffectInput(node); | 274 Node* effect = NodeProperties::GetEffectInput(node); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 275 context, context, effect); | 290 context, context, effect); |
| 276 Node* const load_arguments_map = effect = graph()->NewNode( | 291 Node* const load_arguments_map = effect = graph()->NewNode( |
| 277 simplified()->LoadField(AccessBuilder::ForContextSlot( | 292 simplified()->LoadField(AccessBuilder::ForContextSlot( |
| 278 has_aliased_arguments ? Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX | 293 has_aliased_arguments ? Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX |
| 279 : Context::SLOPPY_ARGUMENTS_MAP_INDEX)), | 294 : Context::SLOPPY_ARGUMENTS_MAP_INDEX)), |
| 280 load_native_context, effect, control); | 295 load_native_context, effect, control); |
| 281 // Actually allocate and initialize the arguments object. | 296 // Actually allocate and initialize the arguments object. |
| 282 AllocationBuilder a(jsgraph(), effect, control); | 297 AllocationBuilder a(jsgraph(), effect, control); |
| 283 Node* properties = jsgraph()->EmptyFixedArrayConstant(); | 298 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
| 284 int length = args_state_info.parameter_count() - 1; // Minus receiver. | 299 int length = args_state_info.parameter_count() - 1; // Minus receiver. |
| 285 STATIC_ASSERT(Heap::kSloppyArgumentsObjectSize == 5 * kPointerSize); | 300 STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize); |
| 286 a.Allocate(Heap::kSloppyArgumentsObjectSize); | 301 a.Allocate(JSSloppyArgumentsObject::kSize); |
| 287 a.Store(AccessBuilder::ForMap(), load_arguments_map); | 302 a.Store(AccessBuilder::ForMap(), load_arguments_map); |
| 288 a.Store(AccessBuilder::ForJSObjectProperties(), properties); | 303 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 289 a.Store(AccessBuilder::ForJSObjectElements(), elements); | 304 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 290 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); | 305 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); |
| 291 a.Store(AccessBuilder::ForArgumentsCallee(), callee); | 306 a.Store(AccessBuilder::ForArgumentsCallee(), callee); |
| 292 RelaxControls(node); | 307 RelaxControls(node); |
| 293 a.FinishAndChange(node); | 308 a.FinishAndChange(node); |
| 294 return Changed(node); | 309 return Changed(node); |
| 295 } else if (type == CreateArgumentsType::kUnmappedArguments) { | 310 } else if (type == CreateArgumentsType::kUnmappedArguments) { |
| 296 // Use inline allocation for all unmapped arguments objects within inlined | 311 // Use inline allocation for all unmapped arguments objects within inlined |
| (...skipping 14 matching lines...) Expand all Loading... |
| 311 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), | 326 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), |
| 312 context, context, effect); | 327 context, context, effect); |
| 313 Node* const load_arguments_map = effect = graph()->NewNode( | 328 Node* const load_arguments_map = effect = graph()->NewNode( |
| 314 simplified()->LoadField(AccessBuilder::ForContextSlot( | 329 simplified()->LoadField(AccessBuilder::ForContextSlot( |
| 315 Context::STRICT_ARGUMENTS_MAP_INDEX)), | 330 Context::STRICT_ARGUMENTS_MAP_INDEX)), |
| 316 load_native_context, effect, control); | 331 load_native_context, effect, control); |
| 317 // Actually allocate and initialize the arguments object. | 332 // Actually allocate and initialize the arguments object. |
| 318 AllocationBuilder a(jsgraph(), effect, control); | 333 AllocationBuilder a(jsgraph(), effect, control); |
| 319 Node* properties = jsgraph()->EmptyFixedArrayConstant(); | 334 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
| 320 int length = args_state_info.parameter_count() - 1; // Minus receiver. | 335 int length = args_state_info.parameter_count() - 1; // Minus receiver. |
| 321 STATIC_ASSERT(Heap::kStrictArgumentsObjectSize == 4 * kPointerSize); | 336 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); |
| 322 a.Allocate(Heap::kStrictArgumentsObjectSize); | 337 a.Allocate(JSStrictArgumentsObject::kSize); |
| 323 a.Store(AccessBuilder::ForMap(), load_arguments_map); | 338 a.Store(AccessBuilder::ForMap(), load_arguments_map); |
| 324 a.Store(AccessBuilder::ForJSObjectProperties(), properties); | 339 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 325 a.Store(AccessBuilder::ForJSObjectElements(), elements); | 340 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 326 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); | 341 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); |
| 327 RelaxControls(node); | 342 RelaxControls(node); |
| 328 a.FinishAndChange(node); | 343 a.FinishAndChange(node); |
| 329 return Changed(node); | 344 return Changed(node); |
| 330 } else if (type == CreateArgumentsType::kRestParameter) { | 345 } else if (type == CreateArgumentsType::kRestParameter) { |
| 331 Handle<SharedFunctionInfo> shared; | 346 Handle<SharedFunctionInfo> shared; |
| 332 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); | 347 if (!state_info.shared_info().ToHandle(&shared)) return NoChange(); |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 return jsgraph()->simplified(); | 772 return jsgraph()->simplified(); |
| 758 } | 773 } |
| 759 | 774 |
| 760 MachineOperatorBuilder* JSCreateLowering::machine() const { | 775 MachineOperatorBuilder* JSCreateLowering::machine() const { |
| 761 return jsgraph()->machine(); | 776 return jsgraph()->machine(); |
| 762 } | 777 } |
| 763 | 778 |
| 764 } // namespace compiler | 779 } // namespace compiler |
| 765 } // namespace internal | 780 } // namespace internal |
| 766 } // namespace v8 | 781 } // namespace v8 |
| OLD | NEW |