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

Side by Side Diff: src/ic/ia32/handler-compiler-ia32.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/handler-compiler.cc ('k') | src/ic/mips/handler-compiler-mips.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 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_IA32 7 #if V8_TARGET_ARCH_IA32
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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 322
323 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 323 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
324 Handle<Name> name) { 324 Handle<Name> name) {
325 if (!label->is_unused()) { 325 if (!label->is_unused()) {
326 __ bind(label); 326 __ bind(label);
327 __ mov(this->name(), Immediate(name)); 327 __ mov(this->name(), Immediate(name));
328 } 328 }
329 } 329 }
330 330
331 331
332 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 332 void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap(
333 // store is successful. 333 Handle<Name> name, Handle<Map> transition) {
334 void NamedStoreHandlerCompiler::GenerateStoreTransition( 334 __ mov(this->name(), Immediate(name));
335 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 335 __ mov(StoreTransitionDescriptor::MapRegister(), Immediate(transition));
336 Register storage_reg, Register value_reg, Register scratch1,
337 Register scratch2, Register unused, Label* miss_label, Label* slow) {
338 int descriptor = transition->LastAdded();
339 DescriptorArray* descriptors = transition->instance_descriptors();
340 PropertyDetails details = descriptors->GetDetails(descriptor);
341 Representation representation = details.representation();
342 DCHECK(!representation.IsNone());
343
344 if (details.type() == CONSTANT) {
345 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
346 __ CmpObject(value_reg, constant);
347 __ j(not_equal, miss_label);
348 } else if (representation.IsSmi()) {
349 __ JumpIfNotSmi(value_reg, miss_label);
350 } else if (representation.IsHeapObject()) {
351 __ JumpIfSmi(value_reg, miss_label);
352 HeapType* field_type = descriptors->GetFieldType(descriptor);
353 HeapType::Iterator<Map> it = field_type->Classes();
354 if (!it.Done()) {
355 Label do_store;
356 while (true) {
357 __ CompareMap(value_reg, it.Current());
358 it.Advance();
359 if (it.Done()) {
360 __ j(not_equal, miss_label);
361 break;
362 }
363 __ j(equal, &do_store, Label::kNear);
364 }
365 __ bind(&do_store);
366 }
367 } else if (representation.IsDouble()) {
368 Label do_store, heap_number;
369 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE);
370
371 __ JumpIfNotSmi(value_reg, &heap_number);
372 __ SmiUntag(value_reg);
373 __ Cvtsi2sd(xmm0, value_reg);
374 __ SmiTag(value_reg);
375 __ jmp(&do_store);
376
377 __ bind(&heap_number);
378 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
379 DONT_DO_SMI_CHECK);
380 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
381
382 __ bind(&do_store);
383 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
384 }
385
386 // Stub never generated for objects that require access checks.
387 DCHECK(!transition->is_access_check_needed());
388
389 // Perform map transition for the receiver if necessary.
390 if (details.type() == FIELD &&
391 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
392 // The properties must be extended before we can store the value.
393 __ mov(ExtendStorageDescriptor::NameRegister(), Immediate(name));
394 __ mov(ExtendStorageDescriptor::MapRegister(), Immediate(transition));
395
396 ExtendStorageStub stub(isolate(),
397 FieldIndex::ForDescriptor(*transition, descriptor),
398 representation);
399 GenerateTailCall(masm(), stub.GetCode());
400 return;
401 }
402
403 // Update the map of the object.
404 __ mov(scratch1, Immediate(transition));
405 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
406
407 // Update the write barrier for the map field.
408 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
409 kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
410
411 if (details.type() == CONSTANT) {
412 DCHECK(value_reg.is(eax));
413 __ ret(0);
414 return;
415 }
416
417 int index = transition->instance_descriptors()->GetFieldIndex(
418 transition->LastAdded());
419
420 // Adjust for the number of properties stored in the object. Even in the
421 // face of a transition we can use the old map here because the size of the
422 // object and the number of in-object properties is not going to change.
423 index -= transition->inobject_properties();
424
425 SmiCheck smi_check =
426 representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
427 // TODO(verwaest): Share this code as a code stub.
428 if (index < 0) {
429 // Set the property straight into the object.
430 int offset = transition->instance_size() + (index * kPointerSize);
431 if (representation.IsDouble()) {
432 __ mov(FieldOperand(receiver_reg, offset), storage_reg);
433 } else {
434 __ mov(FieldOperand(receiver_reg, offset), value_reg);
435 }
436
437 if (!representation.IsSmi()) {
438 // Update the write barrier for the array address.
439 if (!representation.IsDouble()) {
440 __ mov(storage_reg, value_reg);
441 }
442 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
443 kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
444 }
445 } else {
446 // Write to the properties array.
447 int offset = index * kPointerSize + FixedArray::kHeaderSize;
448 // Get the properties array (optimistically).
449 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
450 if (representation.IsDouble()) {
451 __ mov(FieldOperand(scratch1, offset), storage_reg);
452 } else {
453 __ mov(FieldOperand(scratch1, offset), value_reg);
454 }
455
456 if (!representation.IsSmi()) {
457 // Update the write barrier for the array address.
458 if (!representation.IsDouble()) {
459 __ mov(storage_reg, value_reg);
460 }
461 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
462 kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
463 }
464 }
465
466 // Return the value (register eax).
467 DCHECK(value_reg.is(eax));
468 __ ret(0);
469 } 336 }
470 337
471 338
472 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, 339 void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant,
473 Register value_reg, 340 Register value_reg,
474 Label* miss_label) { 341 Label* miss_label) {
475 DCHECK(lookup->representation().IsHeapObject()); 342 __ CmpObject(value_reg, handle(constant, isolate()));
476 __ JumpIfSmi(value_reg, miss_label); 343 __ j(not_equal, miss_label);
477 HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
478 Label do_store;
479 while (true) {
480 __ CompareMap(value_reg, it.Current());
481 it.Advance();
482 if (it.Done()) {
483 __ j(not_equal, miss_label);
484 break;
485 }
486 __ j(equal, &do_store, Label::kNear);
487 }
488 __ bind(&do_store);
489
490 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
491 lookup->representation());
492 GenerateTailCall(masm(), stub.GetCode());
493 } 344 }
494 345
495 346
347 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
348 Register value_reg,
349 Label* miss_label) {
350 __ JumpIfSmi(value_reg, miss_label);
351 HeapType::Iterator<Map> it = field_type->Classes();
352 if (!it.Done()) {
353 Label do_store;
354 while (true) {
355 __ CompareMap(value_reg, it.Current());
356 it.Advance();
357 if (it.Done()) {
358 __ j(not_equal, miss_label);
359 break;
360 }
361 __ j(equal, &do_store, Label::kNear);
362 }
363 __ bind(&do_store);
364 }
365 }
366
367
496 Register PropertyHandlerCompiler::CheckPrototypes( 368 Register PropertyHandlerCompiler::CheckPrototypes(
497 Register object_reg, Register holder_reg, Register scratch1, 369 Register object_reg, Register holder_reg, Register scratch1,
498 Register scratch2, Handle<Name> name, Label* miss, 370 Register scratch2, Handle<Name> name, Label* miss,
499 PrototypeCheckType check) { 371 PrototypeCheckType check) {
500 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 372 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
501 373
502 // Make sure there's no overlap between holder and object registers. 374 // Make sure there's no overlap between holder and object registers.
503 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 375 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
504 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 376 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
505 !scratch2.is(scratch1)); 377 !scratch2.is(scratch1));
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 // Return the generated code. 713 // Return the generated code.
842 return GetCode(kind(), Code::NORMAL, name); 714 return GetCode(kind(), Code::NORMAL, name);
843 } 715 }
844 716
845 717
846 #undef __ 718 #undef __
847 } 719 }
848 } // namespace v8::internal 720 } // namespace v8::internal
849 721
850 #endif // V8_TARGET_ARCH_IA32 722 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ic/handler-compiler.cc ('k') | src/ic/mips/handler-compiler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698