Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: src/compiler/js-create-lowering.cc

Issue 1711883003: [turbofan] Relax restrictions on JSCreate inlining. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@FastNewObjectStub
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 // Retrieves the frame state holding actual argument values. 102 // Retrieves the frame state holding actual argument values.
103 Node* GetArgumentsFrameState(Node* frame_state) { 103 Node* GetArgumentsFrameState(Node* frame_state) {
104 Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state, 0); 104 Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state, 0);
105 FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state); 105 FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state);
106 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor 106 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
107 ? outer_state 107 ? outer_state
108 : frame_state; 108 : frame_state;
109 } 109 }
110 110
111 // Maximum instance size for which allocations will be inlined. 111 // Checks whether allocation using the given target and new.target can be
112 const int kMaxInlineInstanceSize = 64 * kPointerSize; 112 // inlined.
113 113 bool IsAllocationInlineable(Handle<JSFunction> target,
114 // Checks whether allocation using the given constructor can be inlined. 114 Handle<JSFunction> new_target) {
115 bool IsAllocationInlineable(Handle<JSFunction> constructor) { 115 return new_target->has_initial_map() &&
116 // TODO(bmeurer): Further relax restrictions on inlining, i.e. 116 new_target->initial_map()->constructor_or_backpointer() == *target;
117 // instance type and maybe instance size (inobject properties
118 // are limited anyways by the runtime).
119 return constructor->has_initial_map() &&
120 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
121 constructor->initial_map()->instance_size() < kMaxInlineInstanceSize;
122 } 117 }
123 118
124 // When initializing arrays, we'll unfold the loop if the number of 119 // When initializing arrays, we'll unfold the loop if the number of
125 // elements is known to be of this type. 120 // elements is known to be of this type.
126 const int kElementLoopUnrollLimit = 16; 121 const int kElementLoopUnrollLimit = 16;
127 122
128 // Limits up to which context allocations are inlined. 123 // Limits up to which context allocations are inlined.
129 const int kFunctionContextAllocationLimit = 16; 124 const int kFunctionContextAllocationLimit = 16;
130 const int kBlockContextAllocationLimit = 16; 125 const int kBlockContextAllocationLimit = 16;
131 126
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 break; 218 break;
224 } 219 }
225 return NoChange(); 220 return NoChange();
226 } 221 }
227 222
228 Reduction JSCreateLowering::ReduceJSCreate(Node* node) { 223 Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
229 DCHECK_EQ(IrOpcode::kJSCreate, node->opcode()); 224 DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
230 Node* const target = NodeProperties::GetValueInput(node, 0); 225 Node* const target = NodeProperties::GetValueInput(node, 0);
231 Type* const target_type = NodeProperties::GetType(target); 226 Type* const target_type = NodeProperties::GetType(target);
232 Node* const new_target = NodeProperties::GetValueInput(node, 1); 227 Node* const new_target = NodeProperties::GetValueInput(node, 1);
228 Type* const new_target_type = NodeProperties::GetType(new_target);
233 Node* const effect = NodeProperties::GetEffectInput(node); 229 Node* const effect = NodeProperties::GetEffectInput(node);
234 // TODO(turbofan): Add support for NewTarget passed to JSCreate. 230 // Extract constructor and original constructor function.
235 if (target != new_target) return NoChange();
236 // Extract constructor function.
237 if (target_type->IsConstant() && 231 if (target_type->IsConstant() &&
238 target_type->AsConstant()->Value()->IsJSFunction()) { 232 new_target_type->IsConstant() &&
233 new_target_type->AsConstant()->Value()->IsJSFunction()) {
239 Handle<JSFunction> constructor = 234 Handle<JSFunction> constructor =
240 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); 235 Handle<JSFunction>::cast(target_type->AsConstant()->Value());
236 Handle<JSFunction> original_constructor =
237 Handle<JSFunction>::cast(new_target_type->AsConstant()->Value());
241 DCHECK(constructor->IsConstructor()); 238 DCHECK(constructor->IsConstructor());
242 // Force completion of inobject slack tracking before 239 DCHECK(original_constructor->IsConstructor());
243 // generating code to finalize the instance size.
244 constructor->CompleteInobjectSlackTrackingIfActive();
245 240
246 // Check if we can inline the allocation. 241 // Check if we can inline the allocation.
247 if (IsAllocationInlineable(constructor)) { 242 if (IsAllocationInlineable(constructor, original_constructor)) {
248 // Compute instance size from initial map of {constructor}. 243 // Force completion of inobject slack tracking before
249 Handle<Map> initial_map(constructor->initial_map(), isolate()); 244 // generating code to finalize the instance size.
245 original_constructor->CompleteInobjectSlackTrackingIfActive();
246
247 // Compute instance size from initial map of {original_constructor}.
248 Handle<Map> initial_map(original_constructor->initial_map(), isolate());
250 int const instance_size = initial_map->instance_size(); 249 int const instance_size = initial_map->instance_size();
251 250
252 // Add a dependency on the {initial_map} to make sure that this code is 251 // Add a dependency on the {initial_map} to make sure that this code is
253 // deoptimized whenever the {initial_map} of the {constructor} changes. 252 // deoptimized whenever the {initial_map} of the {original_constructor}
253 // changes.
254 dependencies()->AssumeInitialMapCantChange(initial_map); 254 dependencies()->AssumeInitialMapCantChange(initial_map);
255 255
256 // Emit code to allocate the JSObject instance for the {constructor}. 256 // Emit code to allocate the JSObject instance for the
257 // {original_constructor}.
257 AllocationBuilder a(jsgraph(), effect, graph()->start()); 258 AllocationBuilder a(jsgraph(), effect, graph()->start());
258 a.Allocate(instance_size); 259 a.Allocate(instance_size);
259 a.Store(AccessBuilder::ForMap(), initial_map); 260 a.Store(AccessBuilder::ForMap(), initial_map);
260 a.Store(AccessBuilder::ForJSObjectProperties(), 261 a.Store(AccessBuilder::ForJSObjectProperties(),
261 jsgraph()->EmptyFixedArrayConstant()); 262 jsgraph()->EmptyFixedArrayConstant());
262 a.Store(AccessBuilder::ForJSObjectElements(), 263 a.Store(AccessBuilder::ForJSObjectElements(),
263 jsgraph()->EmptyFixedArrayConstant()); 264 jsgraph()->EmptyFixedArrayConstant());
264 for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) { 265 for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
265 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i), 266 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
266 jsgraph()->UndefinedConstant()); 267 jsgraph()->UndefinedConstant());
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 return jsgraph()->simplified(); 1087 return jsgraph()->simplified();
1087 } 1088 }
1088 1089
1089 MachineOperatorBuilder* JSCreateLowering::machine() const { 1090 MachineOperatorBuilder* JSCreateLowering::machine() const {
1090 return jsgraph()->machine(); 1091 return jsgraph()->machine();
1091 } 1092 }
1092 1093
1093 } // namespace compiler 1094 } // namespace compiler
1094 } // namespace internal 1095 } // namespace internal
1095 } // namespace v8 1096 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698