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

Side by Side Diff: src/ic/mips/handler-compiler-mips.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/ia32/handler-compiler-ia32.cc ('k') | src/ic/mips64/handler-compiler-mips64.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_MIPS 7 #if V8_TARGET_ARCH_MIPS
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 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 314
315 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 315 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
316 Handle<Name> name) { 316 Handle<Name> name) {
317 if (!label->is_unused()) { 317 if (!label->is_unused()) {
318 __ bind(label); 318 __ bind(label);
319 __ li(this->name(), Operand(name)); 319 __ li(this->name(), Operand(name));
320 } 320 }
321 } 321 }
322 322
323 323
324 // Generate StoreTransition code, value is passed in a0 register. 324 void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap(
325 // After executing generated code, the receiver_reg and name_reg 325 Handle<Name> name, Handle<Map> transition) {
326 // may be clobbered. 326 __ li(this->name(), Operand(name));
327 void NamedStoreHandlerCompiler::GenerateStoreTransition( 327 __ li(StoreTransitionDescriptor::MapRegister(), Operand(transition));
328 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
329 Register storage_reg, Register value_reg, Register scratch1,
330 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
331 // a0 : value.
332 Label exit;
333
334 int descriptor = transition->LastAdded();
335 DescriptorArray* descriptors = transition->instance_descriptors();
336 PropertyDetails details = descriptors->GetDetails(descriptor);
337 Representation representation = details.representation();
338 DCHECK(!representation.IsNone());
339
340 if (details.type() == CONSTANT) {
341 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
342 __ li(scratch1, constant);
343 __ Branch(miss_label, ne, value_reg, Operand(scratch1));
344 } else if (representation.IsSmi()) {
345 __ JumpIfNotSmi(value_reg, miss_label);
346 } else if (representation.IsHeapObject()) {
347 __ JumpIfSmi(value_reg, miss_label);
348 HeapType* field_type = descriptors->GetFieldType(descriptor);
349 HeapType::Iterator<Map> it = field_type->Classes();
350 Handle<Map> current;
351 if (!it.Done()) {
352 __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
353 Label do_store;
354 while (true) {
355 // Do the CompareMap() directly within the Branch() functions.
356 current = it.Current();
357 it.Advance();
358 if (it.Done()) {
359 __ Branch(miss_label, ne, scratch1, Operand(current));
360 break;
361 }
362 __ Branch(&do_store, eq, scratch1, Operand(current));
363 }
364 __ bind(&do_store);
365 }
366 } else if (representation.IsDouble()) {
367 Label do_store, heap_number;
368 __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
369 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
370 TAG_RESULT, MUTABLE);
371
372 __ JumpIfNotSmi(value_reg, &heap_number);
373 __ SmiUntag(scratch1, value_reg);
374 __ mtc1(scratch1, f6);
375 __ cvt_d_w(f4, f6);
376 __ jmp(&do_store);
377
378 __ bind(&heap_number);
379 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
380 DONT_DO_SMI_CHECK);
381 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
382
383 __ bind(&do_store);
384 __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
385 }
386
387 // Stub never generated for objects that require access checks.
388 DCHECK(!transition->is_access_check_needed());
389
390 // Perform map transition for the receiver if necessary.
391 if (details.type() == FIELD &&
392 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
393 // The properties must be extended before we can store the value.
394 __ li(ExtendStorageDescriptor::NameRegister(), Operand(name));
395 __ li(ExtendStorageDescriptor::MapRegister(), Operand(transition));
396
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 __ li(scratch1, Operand(transition));
407 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
408
409 // Update the write barrier for the map field.
410 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
411 kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
412 OMIT_SMI_CHECK);
413
414 if (details.type() == CONSTANT) {
415 DCHECK(value_reg.is(a0));
416 __ Ret(USE_DELAY_SLOT);
417 __ mov(v0, a0);
418 return;
419 }
420
421 int index = transition->instance_descriptors()->GetFieldIndex(
422 transition->LastAdded());
423
424 // Adjust for the number of properties stored in the object. Even in the
425 // face of a transition we can use the old map here because the size of the
426 // object and the number of in-object properties is not going to change.
427 index -= transition->inobject_properties();
428
429 // TODO(verwaest): Share this code as a code stub.
430 SmiCheck smi_check =
431 representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
432 if (index < 0) {
433 // Set the property straight into the object.
434 int offset = transition->instance_size() + (index * kPointerSize);
435 if (representation.IsDouble()) {
436 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset));
437 } else {
438 __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
439 }
440
441 if (!representation.IsSmi()) {
442 // Update the write barrier for the array address.
443 if (!representation.IsDouble()) {
444 __ mov(storage_reg, value_reg);
445 }
446 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
447 kRAHasNotBeenSaved, kDontSaveFPRegs,
448 EMIT_REMEMBERED_SET, smi_check);
449 }
450 } else {
451 // Write to the properties array.
452 int offset = index * kPointerSize + FixedArray::kHeaderSize;
453 // Get the properties array
454 __ lw(scratch1, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
455 if (representation.IsDouble()) {
456 __ sw(storage_reg, FieldMemOperand(scratch1, offset));
457 } else {
458 __ sw(value_reg, FieldMemOperand(scratch1, offset));
459 }
460
461 if (!representation.IsSmi()) {
462 // Update the write barrier for the array address.
463 if (!representation.IsDouble()) {
464 __ mov(storage_reg, value_reg);
465 }
466 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
467 kRAHasNotBeenSaved, kDontSaveFPRegs,
468 EMIT_REMEMBERED_SET, smi_check);
469 }
470 }
471
472 // Return the value (register v0).
473 DCHECK(value_reg.is(a0));
474 __ bind(&exit);
475 __ Ret(USE_DELAY_SLOT);
476 __ mov(v0, a0);
477 } 328 }
478 329
479 330
480 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, 331 void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant,
481 Register value_reg, 332 Register value_reg,
482 Label* miss_label) { 333 Label* miss_label) {
483 DCHECK(lookup->representation().IsHeapObject()); 334 __ li(scratch1(), handle(constant, isolate()));
484 __ JumpIfSmi(value_reg, miss_label); 335 __ Branch(miss_label, ne, value_reg, Operand(scratch1()));
485 HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
486 __ lw(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
487 Label do_store;
488 Handle<Map> current;
489 while (true) {
490 // Do the CompareMap() directly within the Branch() functions.
491 current = it.Current();
492 it.Advance();
493 if (it.Done()) {
494 __ Branch(miss_label, ne, scratch1(), Operand(current));
495 break;
496 }
497 __ Branch(&do_store, eq, scratch1(), Operand(current));
498 }
499 __ bind(&do_store);
500
501 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
502 lookup->representation());
503 GenerateTailCall(masm(), stub.GetCode());
504 } 336 }
505 337
506 338
339 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
340 Register value_reg,
341 Label* miss_label) {
342 __ JumpIfSmi(value_reg, miss_label);
343 HeapType::Iterator<Map> it = field_type->Classes();
344 if (!it.Done()) {
345 __ lw(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
346 Label do_store;
347 Handle<Map> current;
348 while (true) {
349 // Do the CompareMap() directly within the Branch() functions.
350 current = it.Current();
351 it.Advance();
352 if (it.Done()) {
353 __ Branch(miss_label, ne, scratch1(), Operand(current));
354 break;
355 }
356 __ Branch(&do_store, eq, scratch1(), Operand(current));
357 }
358 __ bind(&do_store);
359 }
360 }
361
362
507 Register PropertyHandlerCompiler::CheckPrototypes( 363 Register PropertyHandlerCompiler::CheckPrototypes(
508 Register object_reg, Register holder_reg, Register scratch1, 364 Register object_reg, Register holder_reg, Register scratch1,
509 Register scratch2, Handle<Name> name, Label* miss, 365 Register scratch2, Handle<Name> name, Label* miss,
510 PrototypeCheckType check) { 366 PrototypeCheckType check) {
511 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 367 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
512 368
513 // Make sure there's no overlap between holder and object registers. 369 // Make sure there's no overlap between holder and object registers.
514 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 370 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
515 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 371 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
516 !scratch2.is(scratch1)); 372 !scratch2.is(scratch1));
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 // Return the generated code. 687 // Return the generated code.
832 return GetCode(kind(), Code::NORMAL, name); 688 return GetCode(kind(), Code::NORMAL, name);
833 } 689 }
834 690
835 691
836 #undef __ 692 #undef __
837 } 693 }
838 } // namespace v8::internal 694 } // namespace v8::internal
839 695
840 #endif // V8_TARGET_ARCH_MIPS 696 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic/ia32/handler-compiler-ia32.cc ('k') | src/ic/mips64/handler-compiler-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698