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

Side by Side Diff: src/builtins/builtins-constructor.cc

Issue 2607233002: [builtins] Add EmitFastNewObject (Closed)
Patch Set: Created 3 years, 11 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 | « src/builtins/builtins-constructor.h ('k') | src/builtins/builtins-promise.cc » ('j') | 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/builtins/builtins-constructor.h" 5 #include "src/builtins/builtins-constructor.h"
6 #include "src/ast/ast.h" 6 #include "src/ast/ast.h"
7 #include "src/builtins/builtins-utils.h" 7 #include "src/builtins/builtins-utils.h"
8 #include "src/builtins/builtins.h" 8 #include "src/builtins/builtins.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stub-assembler.h" 10 #include "src/code-stub-assembler.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 Node* context = Parameter(FastNewClosureDescriptor::kContext); 154 Node* context = Parameter(FastNewClosureDescriptor::kContext);
155 Return(EmitFastNewClosure(shared, context)); 155 Return(EmitFastNewClosure(shared, context));
156 } 156 }
157 157
158 TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) { 158 TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
159 typedef FastNewObjectDescriptor Descriptor; 159 typedef FastNewObjectDescriptor Descriptor;
160 Node* context = Parameter(Descriptor::kContext); 160 Node* context = Parameter(Descriptor::kContext);
161 Node* target = Parameter(Descriptor::kTarget); 161 Node* target = Parameter(Descriptor::kTarget);
162 Node* new_target = Parameter(Descriptor::kNewTarget); 162 Node* new_target = Parameter(Descriptor::kNewTarget);
163 163
164 Label call_runtime(this);
165
166 Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
167 Return(result);
168
169 Bind(&call_runtime);
170 TailCallRuntime(Runtime::kNewObject, context, target, new_target);
171 }
172
173 Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
174 Node* target,
175 Node* new_target) {
176 Variable var_obj(this, MachineRepresentation::kTagged);
177 Label call_runtime(this), end(this);
178
179 Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
180 var_obj.Bind(result);
181 Goto(&end);
182
183 Bind(&call_runtime);
184 var_obj.Bind(CallRuntime(Runtime::kNewObject, context, target, new_target));
185 Goto(&end);
186
187 Bind(&end);
188 return var_obj.value();
189 }
190
191 Node* ConstructorBuiltinsAssembler::EmitFastNewObject(
192 Node* context, Node* target, Node* new_target,
193 CodeAssemblerLabel* call_runtime) {
164 CSA_ASSERT(this, HasInstanceType(target, JS_FUNCTION_TYPE)); 194 CSA_ASSERT(this, HasInstanceType(target, JS_FUNCTION_TYPE));
165 CSA_ASSERT(this, IsJSReceiver(new_target)); 195 CSA_ASSERT(this, IsJSReceiver(new_target));
166 196
167 // Verify that the new target is a JSFunction. 197 // Verify that the new target is a JSFunction.
168 Label runtime(this), fast(this); 198 Label fast(this), end(this);
169 GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast); 199 GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast);
170 Goto(&runtime); 200 Goto(call_runtime);
171
172 Bind(&runtime);
173 TailCallRuntime(Runtime::kNewObject, context, target, new_target);
174 201
175 Bind(&fast); 202 Bind(&fast);
176 203
177 // Load the initial map and verify that it's in fact a map. 204 // Load the initial map and verify that it's in fact a map.
178 Node* initial_map = 205 Node* initial_map =
179 LoadObjectField(new_target, JSFunction::kPrototypeOrInitialMapOffset); 206 LoadObjectField(new_target, JSFunction::kPrototypeOrInitialMapOffset);
180 GotoIf(TaggedIsSmi(initial_map), &runtime); 207 GotoIf(TaggedIsSmi(initial_map), call_runtime);
181 GotoIf(DoesntHaveInstanceType(initial_map, MAP_TYPE), &runtime); 208 GotoIf(DoesntHaveInstanceType(initial_map, MAP_TYPE), call_runtime);
182 209
183 // Fall back to runtime if the target differs from the new target's 210 // Fall back to runtime if the target differs from the new target's
184 // initial map constructor. 211 // initial map constructor.
185 Node* new_target_constructor = 212 Node* new_target_constructor =
186 LoadObjectField(initial_map, Map::kConstructorOrBackPointerOffset); 213 LoadObjectField(initial_map, Map::kConstructorOrBackPointerOffset);
187 GotoIf(WordNotEqual(target, new_target_constructor), &runtime); 214 GotoIf(WordNotEqual(target, new_target_constructor), call_runtime);
188 215
189 Node* instance_size_words = ChangeUint32ToWord(LoadObjectField( 216 Node* instance_size_words = ChangeUint32ToWord(LoadObjectField(
190 initial_map, Map::kInstanceSizeOffset, MachineType::Uint8())); 217 initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
191 Node* instance_size = 218 Node* instance_size =
192 WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2)); 219 WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2));
193 220
194 Node* object = Allocate(instance_size); 221 Node* object = Allocate(instance_size);
195 StoreMapNoWriteBarrier(object, initial_map); 222 StoreMapNoWriteBarrier(object, initial_map);
196 Node* empty_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex); 223 Node* empty_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
197 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, 224 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset,
198 empty_array); 225 empty_array);
199 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, 226 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset,
200 empty_array); 227 empty_array);
201 228
202 instance_size_words = ChangeUint32ToWord(LoadObjectField( 229 instance_size_words = ChangeUint32ToWord(LoadObjectField(
203 initial_map, Map::kInstanceSizeOffset, MachineType::Uint8())); 230 initial_map, Map::kInstanceSizeOffset, MachineType::Uint8()));
204 instance_size = 231 instance_size =
205 WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2)); 232 WordShl(instance_size_words, IntPtrConstant(kPointerSizeLog2));
206 233
207 // Perform in-object slack tracking if requested. 234 // Perform in-object slack tracking if requested.
208 Node* bit_field3 = LoadMapBitField3(initial_map); 235 Node* bit_field3 = LoadMapBitField3(initial_map);
209 Label slack_tracking(this), finalize(this, Label::kDeferred), done(this); 236 Label slack_tracking(this), finalize(this, Label::kDeferred), done(this);
210 GotoIf(IsSetWord32<Map::ConstructionCounter>(bit_field3), &slack_tracking); 237 GotoIf(IsSetWord32<Map::ConstructionCounter>(bit_field3), &slack_tracking);
211 238
212 // Initialize remaining fields. 239 // Initialize remaining fields.
213 { 240 {
214 Comment("no slack tracking"); 241 Comment("no slack tracking");
215 InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize), 242 InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
216 instance_size, Heap::kUndefinedValueRootIndex); 243 instance_size, Heap::kUndefinedValueRootIndex);
217 Return(object); 244 Goto(&end);
218 } 245 }
219 246
220 { 247 {
221 Bind(&slack_tracking); 248 Bind(&slack_tracking);
222 249
223 // Decrease generous allocation count. 250 // Decrease generous allocation count.
224 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); 251 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
225 Comment("update allocation count"); 252 Comment("update allocation count");
226 Node* new_bit_field3 = Int32Sub( 253 Node* new_bit_field3 = Int32Sub(
227 bit_field3, Int32Constant(1 << Map::ConstructionCounter::kShift)); 254 bit_field3, Int32Constant(1 << Map::ConstructionCounter::kShift));
228 StoreObjectFieldNoWriteBarrier(initial_map, Map::kBitField3Offset, 255 StoreObjectFieldNoWriteBarrier(initial_map, Map::kBitField3Offset,
229 new_bit_field3, 256 new_bit_field3,
230 MachineRepresentation::kWord32); 257 MachineRepresentation::kWord32);
231 GotoIf(IsClearWord32<Map::ConstructionCounter>(new_bit_field3), &finalize); 258 GotoIf(IsClearWord32<Map::ConstructionCounter>(new_bit_field3), &finalize);
232 259
233 Node* unused_fields = LoadObjectField( 260 Node* unused_fields = LoadObjectField(
234 initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8()); 261 initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
235 Node* used_size = 262 Node* used_size =
236 IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields), 263 IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields),
237 IntPtrConstant(kPointerSizeLog2))); 264 IntPtrConstant(kPointerSizeLog2)));
238 265
239 Comment("initialize filler fields (no finalize)"); 266 Comment("initialize filler fields (no finalize)");
240 InitializeFieldsWithRoot(object, used_size, instance_size, 267 InitializeFieldsWithRoot(object, used_size, instance_size,
241 Heap::kOnePointerFillerMapRootIndex); 268 Heap::kOnePointerFillerMapRootIndex);
242 269
243 Comment("initialize undefined fields (no finalize)"); 270 Comment("initialize undefined fields (no finalize)");
244 InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize), 271 InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
245 used_size, Heap::kUndefinedValueRootIndex); 272 used_size, Heap::kUndefinedValueRootIndex);
246 Return(object); 273 Goto(&end);
247 } 274 }
248 275
249 { 276 {
250 // Finalize the instance size. 277 // Finalize the instance size.
251 Bind(&finalize); 278 Bind(&finalize);
252 279
253 Node* unused_fields = LoadObjectField( 280 Node* unused_fields = LoadObjectField(
254 initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8()); 281 initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8());
255 Node* used_size = 282 Node* used_size =
256 IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields), 283 IntPtrSub(instance_size, WordShl(ChangeUint32ToWord(unused_fields),
257 IntPtrConstant(kPointerSizeLog2))); 284 IntPtrConstant(kPointerSizeLog2)));
258 285
259 Comment("initialize filler fields (finalize)"); 286 Comment("initialize filler fields (finalize)");
260 InitializeFieldsWithRoot(object, used_size, instance_size, 287 InitializeFieldsWithRoot(object, used_size, instance_size,
261 Heap::kOnePointerFillerMapRootIndex); 288 Heap::kOnePointerFillerMapRootIndex);
262 289
263 Comment("initialize undefined fields (finalize)"); 290 Comment("initialize undefined fields (finalize)");
264 InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize), 291 InitializeFieldsWithRoot(object, IntPtrConstant(JSObject::kHeaderSize),
265 used_size, Heap::kUndefinedValueRootIndex); 292 used_size, Heap::kUndefinedValueRootIndex);
266 293
267 CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map); 294 CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map);
268 Return(object); 295 Goto(&end);
269 } 296 }
297
298 Bind(&end);
299 return object;
270 } 300 }
271 301
272 Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext( 302 Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext(
273 Node* function, Node* slots, Node* context, ScopeType scope_type) { 303 Node* function, Node* slots, Node* context, ScopeType scope_type) {
274 slots = ChangeUint32ToWord(slots); 304 slots = ChangeUint32ToWord(slots);
275 305
276 // TODO(ishell): Use CSA::OptimalParameterMode() here. 306 // TODO(ishell): Use CSA::OptimalParameterMode() here.
277 CodeStubAssembler::ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; 307 CodeStubAssembler::ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS;
278 Node* min_context_slots = IntPtrConstant(Context::MIN_CONTEXT_SLOTS); 308 Node* min_context_slots = IntPtrConstant(Context::MIN_CONTEXT_SLOTS);
279 Node* length = IntPtrAdd(slots, min_context_slots); 309 Node* length = IntPtrAdd(slots, min_context_slots);
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 case 6: 763 case 6:
734 return FastCloneShallowObject6(); 764 return FastCloneShallowObject6();
735 default: 765 default:
736 UNREACHABLE(); 766 UNREACHABLE();
737 } 767 }
738 return Handle<Code>::null(); 768 return Handle<Code>::null();
739 } 769 }
740 770
741 } // namespace internal 771 } // namespace internal
742 } // namespace v8 772 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-constructor.h ('k') | src/builtins/builtins-promise.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698