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

Side by Side Diff: src/ic/arm64/handler-compiler-arm64.cc

Issue 609463003: Hydrogenize (and share) part of StoreTransition handler as a StoreTransitionStub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebasing Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/ic/arm/handler-compiler-arm.cc ('k') | src/ic/handler-compiler.h » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/ic/call-optimization.h" 9 #include "src/ic/call-optimization.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 363
364 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 364 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
365 Handle<Name> name) { 365 Handle<Name> name) {
366 if (!label->is_unused()) { 366 if (!label->is_unused()) {
367 __ Bind(label); 367 __ Bind(label);
368 __ Mov(this->name(), Operand(name)); 368 __ Mov(this->name(), Operand(name));
369 } 369 }
370 } 370 }
371 371
372 372
373 // Generate StoreTransition code, value is passed in x0 register. 373 void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap(
374 // When leaving generated code after success, the receiver_reg and storage_reg 374 Handle<Name> name, Handle<Map> transition) {
375 // may be clobbered. Upon branch to miss_label, the receiver and name registers 375 __ Mov(this->name(), Operand(name));
376 // have their original values. 376 __ Mov(StoreTransitionDescriptor::MapRegister(), Operand(transition));
377 void NamedStoreHandlerCompiler::GenerateStoreTransition(
378 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
379 Register storage_reg, Register value_reg, Register scratch1,
380 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
381 Label exit;
382
383 DCHECK(!AreAliased(receiver_reg, storage_reg, value_reg, scratch1, scratch2,
384 scratch3));
385
386 // We don't need scratch3.
387 scratch3 = NoReg;
388
389 int descriptor = transition->LastAdded();
390 DescriptorArray* descriptors = transition->instance_descriptors();
391 PropertyDetails details = descriptors->GetDetails(descriptor);
392 Representation representation = details.representation();
393 DCHECK(!representation.IsNone());
394
395 if (details.type() == CONSTANT) {
396 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
397 __ LoadObject(scratch1, constant);
398 __ Cmp(value_reg, scratch1);
399 __ B(ne, miss_label);
400 } else if (representation.IsSmi()) {
401 __ JumpIfNotSmi(value_reg, miss_label);
402 } else if (representation.IsHeapObject()) {
403 __ JumpIfSmi(value_reg, miss_label);
404 HeapType* field_type = descriptors->GetFieldType(descriptor);
405 HeapType::Iterator<Map> it = field_type->Classes();
406 if (!it.Done()) {
407 __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
408 Label do_store;
409 while (true) {
410 __ CompareMap(scratch1, it.Current());
411 it.Advance();
412 if (it.Done()) {
413 __ B(ne, miss_label);
414 break;
415 }
416 __ B(eq, &do_store);
417 }
418 __ Bind(&do_store);
419 }
420 } else if (representation.IsDouble()) {
421 UseScratchRegisterScope temps(masm());
422 DoubleRegister temp_double = temps.AcquireD();
423 __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
424
425 Label do_store;
426 __ JumpIfSmi(value_reg, &do_store);
427
428 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
429 DONT_DO_SMI_CHECK);
430 __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
431
432 __ Bind(&do_store);
433 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double,
434 NoReg, MUTABLE);
435 }
436
437 // Stub never generated for objects that require access checks.
438 DCHECK(!transition->is_access_check_needed());
439
440 // Perform map transition for the receiver if necessary.
441 if (details.type() == FIELD &&
442 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
443 // The properties must be extended before we can store the value.
444 __ Mov(ExtendStorageDescriptor::NameRegister(), Operand(name));
445 __ Mov(ExtendStorageDescriptor::MapRegister(), Operand(transition));
446
447 ExtendStorageStub stub(isolate(),
448 FieldIndex::ForDescriptor(*transition, descriptor),
449 representation);
450 GenerateTailCall(masm(), stub.GetCode());
451 return;
452 }
453
454 // Update the map of the object.
455 __ Mov(scratch1, Operand(transition));
456 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
457
458 // Update the write barrier for the map field.
459 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
460 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
461 OMIT_SMI_CHECK);
462
463 if (details.type() == CONSTANT) {
464 DCHECK(value_reg.is(x0));
465 __ Ret();
466 return;
467 }
468
469 int index = transition->instance_descriptors()->GetFieldIndex(
470 transition->LastAdded());
471
472 // Adjust for the number of properties stored in the object. Even in the
473 // face of a transition we can use the old map here because the size of the
474 // object and the number of in-object properties is not going to change.
475 index -= transition->inobject_properties();
476
477 // TODO(verwaest): Share this code as a code stub.
478 SmiCheck smi_check =
479 representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
480 Register prop_reg = representation.IsDouble() ? storage_reg : value_reg;
481 if (index < 0) {
482 // Set the property straight into the object.
483 int offset = transition->instance_size() + (index * kPointerSize);
484 __ Str(prop_reg, FieldMemOperand(receiver_reg, offset));
485
486 if (!representation.IsSmi()) {
487 // Update the write barrier for the array address.
488 if (!representation.IsDouble()) {
489 __ Mov(storage_reg, value_reg);
490 }
491 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
492 kLRHasNotBeenSaved, kDontSaveFPRegs,
493 EMIT_REMEMBERED_SET, smi_check);
494 }
495 } else {
496 // Write to the properties array.
497 int offset = index * kPointerSize + FixedArray::kHeaderSize;
498 // Get the properties array
499 __ Ldr(scratch1,
500 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
501 __ Str(prop_reg, FieldMemOperand(scratch1, offset));
502
503 if (!representation.IsSmi()) {
504 // Update the write barrier for the array address.
505 if (!representation.IsDouble()) {
506 __ Mov(storage_reg, value_reg);
507 }
508 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
509 kLRHasNotBeenSaved, kDontSaveFPRegs,
510 EMIT_REMEMBERED_SET, smi_check);
511 }
512 }
513
514 __ Bind(&exit);
515 // Return the value (register x0).
516 DCHECK(value_reg.is(x0));
517 __ Ret();
518 } 377 }
519 378
520 379
521 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, 380 void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant,
522 Register value_reg, 381 Register value_reg,
523 Label* miss_label) { 382 Label* miss_label) {
524 DCHECK(lookup->representation().IsHeapObject()); 383 __ LoadObject(scratch1(), handle(constant, isolate()));
525 __ JumpIfSmi(value_reg, miss_label); 384 __ Cmp(value_reg, scratch1());
526 HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes(); 385 __ B(ne, miss_label);
527 __ Ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
528 Label do_store;
529 while (true) {
530 __ CompareMap(scratch1(), it.Current());
531 it.Advance();
532 if (it.Done()) {
533 __ B(ne, miss_label);
534 break;
535 }
536 __ B(eq, &do_store);
537 }
538 __ Bind(&do_store);
539
540 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
541 lookup->representation());
542 GenerateTailCall(masm(), stub.GetCode());
543 } 386 }
544 387
545 388
389 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
390 Register value_reg,
391 Label* miss_label) {
392 __ JumpIfSmi(value_reg, miss_label);
393 HeapType::Iterator<Map> it = field_type->Classes();
394 if (!it.Done()) {
395 __ Ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
396 Label do_store;
397 while (true) {
398 __ CompareMap(scratch1(), it.Current());
399 it.Advance();
400 if (it.Done()) {
401 __ B(ne, miss_label);
402 break;
403 }
404 __ B(eq, &do_store);
405 }
406 __ Bind(&do_store);
407 }
408 }
409
410
546 Register PropertyHandlerCompiler::CheckPrototypes( 411 Register PropertyHandlerCompiler::CheckPrototypes(
547 Register object_reg, Register holder_reg, Register scratch1, 412 Register object_reg, Register holder_reg, Register scratch1,
548 Register scratch2, Handle<Name> name, Label* miss, 413 Register scratch2, Handle<Name> name, Label* miss,
549 PrototypeCheckType check) { 414 PrototypeCheckType check) {
550 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 415 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
551 416
552 // object_reg and holder_reg registers can alias. 417 // object_reg and holder_reg registers can alias.
553 DCHECK(!AreAliased(object_reg, scratch1, scratch2)); 418 DCHECK(!AreAliased(object_reg, scratch1, scratch2));
554 DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); 419 DCHECK(!AreAliased(holder_reg, scratch1, scratch2));
555 420
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 // Return the generated code. 703 // Return the generated code.
839 return GetCode(kind(), Code::FAST, name); 704 return GetCode(kind(), Code::FAST, name);
840 } 705 }
841 706
842 707
843 #undef __ 708 #undef __
844 } 709 }
845 } // namespace v8::internal 710 } // namespace v8::internal
846 711
847 #endif // V8_TARGET_ARCH_IA32 712 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ic/arm/handler-compiler-arm.cc ('k') | src/ic/handler-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698