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 |