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

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

Powered by Google App Engine
This is Rietveld 408576698