Chromium Code Reviews| 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/builtins/builtins-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
| 6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
| 7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" |
| 8 #include "src/interface-descriptors.h" | 8 #include "src/interface-descriptors.h" |
| 9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
| 10 | 10 |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 Node* length = assembler.IntPtrSub(frame_length, formal_parameter_count); | 302 Node* length = assembler.IntPtrSub(frame_length, formal_parameter_count); |
| 303 | 303 |
| 304 // Allocate the actual FixedArray for the elements. | 304 // Allocate the actual FixedArray for the elements. |
| 305 Generate_NewArgumentsElements(&assembler, frame, length); | 305 Generate_NewArgumentsElements(&assembler, frame, length); |
| 306 | 306 |
| 307 // No rest parameters, return an empty FixedArray. | 307 // No rest parameters, return an empty FixedArray. |
| 308 assembler.Bind(&if_empty); | 308 assembler.Bind(&if_empty); |
| 309 assembler.Return(assembler.EmptyFixedArrayConstant()); | 309 assembler.Return(assembler.EmptyFixedArrayConstant()); |
| 310 } | 310 } |
| 311 | 311 |
| 312 void Builtins::Generate_FastNewObject(compiler::CodeAssemblerState* state) { | |
|
mvstanton
2016/12/29 10:24:33
TF_BUILTIN is a nice helper if you like.
| |
| 313 typedef CodeStubAssembler::Label Label; | |
| 314 typedef compiler::Node Node; | |
| 315 typedef FastNewObjectDescriptor Descriptor; | |
| 316 CodeStubAssembler assembler(state); | |
| 317 | |
| 318 Node* context = assembler.Parameter(Descriptor::kContext); | |
| 319 Node* target = assembler.Parameter(Descriptor::kTarget); | |
| 320 Node* new_target = assembler.Parameter(Descriptor::kNewTarget); | |
| 321 | |
| 322 CSA_ASSERT(&assembler, assembler.HasInstanceType(target, JS_FUNCTION_TYPE)); | |
| 323 CSA_ASSERT(&assembler, assembler.IsJSReceiver(new_target)); | |
| 324 | |
| 325 // Verify that the new target is a JSFunction. | |
| 326 Label runtime(&assembler), fast(&assembler); | |
| 327 assembler.GotoIf(assembler.HasInstanceType(new_target, JS_FUNCTION_TYPE), | |
| 328 &fast); | |
| 329 assembler.Goto(&runtime); | |
| 330 | |
| 331 assembler.Bind(&runtime); | |
| 332 assembler.TailCallRuntime(Runtime::kNewObject, context, target, new_target); | |
| 333 | |
| 334 assembler.Bind(&fast); | |
| 335 | |
| 336 // Load the initial map and verify that it's in fact a map. | |
| 337 Node* initial_map = assembler.LoadObjectField( | |
| 338 new_target, JSFunction::kPrototypeOrInitialMapOffset); | |
| 339 assembler.GotoIf(assembler.TaggedIsSmi(initial_map), &runtime); | |
| 340 assembler.GotoIf(assembler.DoesntHaveInstanceType(initial_map, MAP_TYPE), | |
| 341 &runtime); | |
| 342 | |
| 343 // Fall back to runtime if the target differs from the new target's | |
| 344 // initial map constructor. | |
| 345 Node* new_target_constructor = assembler.LoadObjectField( | |
| 346 initial_map, Map::kConstructorOrBackPointerOffset); | |
| 347 assembler.GotoIf(assembler.WordNotEqual(target, new_target_constructor), | |
| 348 &runtime); | |
| 349 | |
| 350 Node* instance_size_words = | |
| 351 assembler.ChangeUint32ToWord(assembler.LoadObjectField( | |
| 352 initial_map, Map::kInstanceSizeOffset, MachineType::Uint8())); | |
| 353 Node* instance_size = assembler.WordShl( | |
| 354 instance_size_words, assembler.IntPtrConstant(kPointerSizeLog2)); | |
| 355 | |
| 356 Node* object = assembler.Allocate(instance_size); | |
| 357 assembler.StoreMapNoWriteBarrier(object, initial_map); | |
| 358 Node* empty_array = assembler.LoadRoot(Heap::kEmptyFixedArrayRootIndex); | |
| 359 assembler.StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, | |
| 360 empty_array); | |
| 361 assembler.StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, | |
| 362 empty_array); | |
| 363 | |
| 364 instance_size_words = assembler.ChangeUint32ToWord(assembler.LoadObjectField( | |
| 365 initial_map, Map::kInstanceSizeOffset, MachineType::Uint8())); | |
| 366 instance_size = assembler.WordShl(instance_size_words, | |
| 367 assembler.IntPtrConstant(kPointerSizeLog2)); | |
| 368 | |
| 369 // Perform in-object slack tracking if requested. | |
| 370 Node* bit_field3 = assembler.LoadMapBitField3(initial_map); | |
| 371 Label slack_tracking(&assembler), finalize(&assembler, Label::kDeferred), | |
| 372 done(&assembler); | |
| 373 assembler.GotoIf(assembler.IsSetWord32<Map::ConstructionCounter>(bit_field3), | |
| 374 &slack_tracking); | |
| 375 | |
| 376 // Initialize remaining fields. | |
| 377 { | |
| 378 assembler.Comment("no slack tracking"); | |
| 379 assembler.InitializeFieldsWithRoot( | |
| 380 object, assembler.IntPtrConstant(JSObject::kHeaderSize), instance_size, | |
| 381 Heap::kUndefinedValueRootIndex); | |
| 382 assembler.Return(object); | |
| 383 } | |
| 384 | |
| 385 { | |
| 386 assembler.Bind(&slack_tracking); | |
| 387 | |
| 388 // Decrease generous allocation count. | |
| 389 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); | |
| 390 assembler.Comment("update allocation count"); | |
| 391 Node* new_bit_field3 = assembler.Int32Sub( | |
| 392 bit_field3, | |
| 393 assembler.Int32Constant(1 << Map::ConstructionCounter::kShift)); | |
| 394 assembler.StoreObjectFieldNoWriteBarrier(initial_map, Map::kBitField3Offset, | |
| 395 new_bit_field3, | |
| 396 MachineRepresentation::kWord32); | |
| 397 assembler.GotoIf( | |
| 398 assembler.IsClearWord32<Map::ConstructionCounter>(new_bit_field3), | |
| 399 &finalize); | |
| 400 | |
| 401 Node* unused_fields = assembler.LoadObjectField( | |
| 402 initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8()); | |
| 403 Node* used_size = assembler.IntPtrSub( | |
| 404 instance_size, | |
| 405 assembler.WordShl(assembler.ChangeUint32ToWord(unused_fields), | |
| 406 assembler.IntPtrConstant(kPointerSizeLog2))); | |
| 407 | |
| 408 assembler.Comment("initialize filler fields (no finalize)"); | |
| 409 assembler.InitializeFieldsWithRoot(object, used_size, instance_size, | |
| 410 Heap::kOnePointerFillerMapRootIndex); | |
| 411 | |
| 412 assembler.Comment("initialize undefined fields (no finalize)"); | |
| 413 assembler.InitializeFieldsWithRoot( | |
| 414 object, assembler.IntPtrConstant(JSObject::kHeaderSize), used_size, | |
| 415 Heap::kUndefinedValueRootIndex); | |
| 416 assembler.Return(object); | |
| 417 } | |
| 418 | |
| 419 { | |
| 420 // Finalize the instance size. | |
| 421 assembler.Bind(&finalize); | |
| 422 | |
| 423 Node* unused_fields = assembler.LoadObjectField( | |
| 424 initial_map, Map::kUnusedPropertyFieldsOffset, MachineType::Uint8()); | |
| 425 Node* used_size = assembler.IntPtrSub( | |
| 426 instance_size, | |
| 427 assembler.WordShl(assembler.ChangeUint32ToWord(unused_fields), | |
| 428 assembler.IntPtrConstant(kPointerSizeLog2))); | |
| 429 | |
| 430 assembler.Comment("initialize filler fields (finalize)"); | |
| 431 assembler.InitializeFieldsWithRoot(object, used_size, instance_size, | |
| 432 Heap::kOnePointerFillerMapRootIndex); | |
| 433 | |
| 434 assembler.Comment("initialize undefined fields (finalize)"); | |
| 435 assembler.InitializeFieldsWithRoot( | |
| 436 object, assembler.IntPtrConstant(JSObject::kHeaderSize), used_size, | |
| 437 Heap::kUndefinedValueRootIndex); | |
| 438 | |
| 439 assembler.CallRuntime(Runtime::kFinalizeInstanceSize, context, initial_map); | |
| 440 assembler.Return(object); | |
| 441 } | |
| 442 } | |
| 443 | |
| 312 void Builtins::Generate_ReturnReceiver(compiler::CodeAssemblerState* state) { | 444 void Builtins::Generate_ReturnReceiver(compiler::CodeAssemblerState* state) { |
| 313 CodeStubAssembler assembler(state); | 445 CodeStubAssembler assembler(state); |
| 314 assembler.Return(assembler.Parameter(0)); | 446 assembler.Return(assembler.Parameter(0)); |
| 315 } | 447 } |
| 316 | 448 |
| 317 } // namespace internal | 449 } // namespace internal |
| 318 } // namespace v8 | 450 } // namespace v8 |
| OLD | NEW |