Revision f230a1cf deps/v8/src/objects.cc

View differences:

deps/v8/src/objects.cc
28 28
#include "v8.h"
29 29

  
30 30
#include "accessors.h"
31
#include "allocation-site-scopes.h"
31 32
#include "api.h"
32 33
#include "arguments.h"
33 34
#include "bootstrapper.h"
......
142 143
}
143 144

  
144 145

  
146
Handle<Object> Object::GetPropertyWithReceiver(
147
    Handle<Object> object,
148
    Handle<Object> receiver,
149
    Handle<Name> name,
150
    PropertyAttributes* attributes) {
151
  LookupResult lookup(name->GetIsolate());
152
  object->Lookup(*name, &lookup);
153
  Handle<Object> result =
154
      GetProperty(object, receiver, &lookup, name, attributes);
155
  ASSERT(*attributes <= ABSENT);
156
  return result;
157
}
158

  
159

  
145 160
MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
146 161
                                             Name* name,
147 162
                                             PropertyAttributes* attributes) {
......
328 343
}
329 344

  
330 345

  
331
MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
332
                                               Object* structure,
333
                                               Name* name) {
346
Handle<FixedArray> JSObject::EnsureWritableFastElements(
347
    Handle<JSObject> object) {
348
  CALL_HEAP_FUNCTION(object->GetIsolate(),
349
                     object->EnsureWritableFastElements(),
350
                     FixedArray);
351
}
352

  
353

  
354
Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
355
                                                 Handle<Object> receiver,
356
                                                 Handle<Object> structure,
357
                                                 Handle<Name> name) {
334 358
  Isolate* isolate = name->GetIsolate();
335 359
  // To accommodate both the old and the new api we switch on the
336 360
  // data structure used to store the callbacks.  Eventually foreign
......
338 362
  if (structure->IsForeign()) {
339 363
    AccessorDescriptor* callback =
340 364
        reinterpret_cast<AccessorDescriptor*>(
341
            Foreign::cast(structure)->foreign_address());
342
    MaybeObject* value = (callback->getter)(isolate, receiver, callback->data);
343
    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
344
    return value;
365
            Handle<Foreign>::cast(structure)->foreign_address());
366
    CALL_HEAP_FUNCTION(isolate,
367
                       (callback->getter)(isolate, *receiver, callback->data),
368
                       Object);
345 369
  }
346 370

  
347 371
  // api style callbacks.
348 372
  if (structure->IsAccessorInfo()) {
349
    if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) {
350
      Handle<Object> name_handle(name, isolate);
351
      Handle<Object> receiver_handle(receiver, isolate);
352
      Handle<Object> args[2] = { name_handle, receiver_handle };
373
    Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
374
    if (!accessor_info->IsCompatibleReceiver(*receiver)) {
375
      Handle<Object> args[2] = { name, receiver };
353 376
      Handle<Object> error =
354 377
          isolate->factory()->NewTypeError("incompatible_method_receiver",
355 378
                                           HandleVector(args,
356 379
                                                        ARRAY_SIZE(args)));
357
      return isolate->Throw(*error);
380
      isolate->Throw(*error);
381
      return Handle<Object>::null();
358 382
    }
359 383
    // TODO(rossberg): Handling symbols in the API requires changing the API,
360 384
    // so we do not support it for now.
361
    if (name->IsSymbol()) return isolate->heap()->undefined_value();
385
    if (name->IsSymbol()) return isolate->factory()->undefined_value();
362 386
    if (structure->IsDeclaredAccessorInfo()) {
363
      return GetDeclaredAccessorProperty(receiver,
364
                                         DeclaredAccessorInfo::cast(structure),
365
                                         isolate);
387
      CALL_HEAP_FUNCTION(
388
          isolate,
389
          GetDeclaredAccessorProperty(*receiver,
390
                                      DeclaredAccessorInfo::cast(*structure),
391
                                      isolate),
392
          Object);
366 393
    }
367
    ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure);
368
    Object* fun_obj = data->getter();
394

  
395
    Handle<ExecutableAccessorInfo> data =
396
        Handle<ExecutableAccessorInfo>::cast(structure);
369 397
    v8::AccessorGetterCallback call_fun =
370
        v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
371
    if (call_fun == NULL) return isolate->heap()->undefined_value();
398
        v8::ToCData<v8::AccessorGetterCallback>(data->getter());
399
    if (call_fun == NULL) return isolate->factory()->undefined_value();
400

  
372 401
    HandleScope scope(isolate);
373
    JSObject* self = JSObject::cast(receiver);
374
    Handle<String> key(String::cast(name));
375
    LOG(isolate, ApiNamedPropertyAccess("load", self, name));
376
    PropertyCallbackArguments args(isolate, data->data(), self, this);
402
    Handle<JSObject> self = Handle<JSObject>::cast(receiver);
403
    Handle<String> key = Handle<String>::cast(name);
404
    LOG(isolate, ApiNamedPropertyAccess("load", *self, *name));
405
    PropertyCallbackArguments args(isolate, data->data(), *self, *object);
377 406
    v8::Handle<v8::Value> result =
378 407
        args.Call(call_fun, v8::Utils::ToLocal(key));
379
    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
408
    RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
380 409
    if (result.IsEmpty()) {
381
      return isolate->heap()->undefined_value();
410
      return isolate->factory()->undefined_value();
382 411
    }
383
    Object* return_value = *v8::Utils::OpenHandle(*result);
412
    Handle<Object> return_value = v8::Utils::OpenHandle(*result);
384 413
    return_value->VerifyApiCallResultType();
385
    return return_value;
414
    return scope.CloseAndEscape(return_value);
386 415
  }
387 416

  
388 417
  // __defineGetter__ callback
389
  if (structure->IsAccessorPair()) {
390
    Object* getter = AccessorPair::cast(structure)->getter();
391
    if (getter->IsSpecFunction()) {
392
      // TODO(rossberg): nicer would be to cast to some JSCallable here...
393
      return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
394
    }
395
    // Getter is not a function.
396
    return isolate->heap()->undefined_value();
418
  Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
419
                        isolate);
420
  if (getter->IsSpecFunction()) {
421
    // TODO(rossberg): nicer would be to cast to some JSCallable here...
422
    CALL_HEAP_FUNCTION(
423
        isolate,
424
        object->GetPropertyWithDefinedGetter(*receiver,
425
                                             JSReceiver::cast(*getter)),
426
        Object);
397 427
  }
398

  
399
  UNREACHABLE();
400
  return NULL;
428
  // Getter is not a function.
429
  return isolate->factory()->undefined_value();
401 430
}
402 431

  
403 432

  
......
455 484
                                              StrictModeFlag strict_mode) {
456 485
  Isolate* isolate = proxy->GetIsolate();
457 486
  Handle<String> name = isolate->factory()->Uint32ToString(index);
458
  CALL_HEAP_FUNCTION(isolate,
459
                     proxy->SetPropertyWithHandler(
460
                         *receiver, *name, *value, NONE, strict_mode),
461
                     Object);
487
  return SetPropertyWithHandler(
488
      proxy, receiver, name, value, NONE, strict_mode);
462 489
}
463 490

  
464 491

  
465
bool JSProxy::HasElementWithHandler(uint32_t index) {
466
  String* name;
467
  MaybeObject* maybe = GetHeap()->Uint32ToString(index);
468
  if (!maybe->To<String>(&name)) return maybe;
469
  return HasPropertyWithHandler(name);
492
bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) {
493
  Isolate* isolate = proxy->GetIsolate();
494
  Handle<String> name = isolate->factory()->Uint32ToString(index);
495
  return HasPropertyWithHandler(proxy, name);
470 496
}
471 497

  
472 498

  
......
496 522

  
497 523

  
498 524
// Only deal with CALLBACKS and INTERCEPTOR
499
MaybeObject* JSObject::GetPropertyWithFailedAccessCheck(
500
    Object* receiver,
525
Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
526
    Handle<JSObject> object,
527
    Handle<Object> receiver,
501 528
    LookupResult* result,
502
    Name* name,
529
    Handle<Name> name,
503 530
    PropertyAttributes* attributes) {
531
  Isolate* isolate = name->GetIsolate();
504 532
  if (result->IsProperty()) {
505 533
    switch (result->type()) {
506 534
      case CALLBACKS: {
507 535
        // Only allow API accessors.
508
        Object* obj = result->GetCallbackObject();
509
        if (obj->IsAccessorInfo()) {
510
          AccessorInfo* info = AccessorInfo::cast(obj);
511
          if (info->all_can_read()) {
512
            *attributes = result->GetAttributes();
513
            return result->holder()->GetPropertyWithCallback(
514
                receiver, result->GetCallbackObject(), name);
515
          }
516
        } else if (obj->IsAccessorPair()) {
517
          AccessorPair* pair = AccessorPair::cast(obj);
518
          if (pair->all_can_read()) {
519
            return result->holder()->GetPropertyWithCallback(
520
                receiver, result->GetCallbackObject(), name);
521
          }
536
        Handle<Object> callback_obj(result->GetCallbackObject(), isolate);
537
        if (callback_obj->IsAccessorInfo()) {
538
          if (!AccessorInfo::cast(*callback_obj)->all_can_read()) break;
539
          *attributes = result->GetAttributes();
540
          // Fall through to GetPropertyWithCallback.
541
        } else if (callback_obj->IsAccessorPair()) {
542
          if (!AccessorPair::cast(*callback_obj)->all_can_read()) break;
543
          // Fall through to GetPropertyWithCallback.
544
        } else {
545
          break;
522 546
        }
523
        break;
547
        Handle<JSObject> holder(result->holder(), isolate);
548
        return GetPropertyWithCallback(holder, receiver, callback_obj, name);
524 549
      }
525 550
      case NORMAL:
526 551
      case FIELD:
527 552
      case CONSTANT: {
528 553
        // Search ALL_CAN_READ accessors in prototype chain.
529
        LookupResult r(GetIsolate());
530
        result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
554
        LookupResult r(isolate);
555
        result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
531 556
        if (r.IsProperty()) {
532
          return GetPropertyWithFailedAccessCheck(receiver,
533
                                                  &r,
534
                                                  name,
535
                                                  attributes);
557
          return GetPropertyWithFailedAccessCheck(
558
              object, receiver, &r, name, attributes);
536 559
        }
537 560
        break;
538 561
      }
539 562
      case INTERCEPTOR: {
540 563
        // If the object has an interceptor, try real named properties.
541 564
        // No access check in GetPropertyAttributeWithInterceptor.
542
        LookupResult r(GetIsolate());
543
        result->holder()->LookupRealNamedProperty(name, &r);
565
        LookupResult r(isolate);
566
        result->holder()->LookupRealNamedProperty(*name, &r);
544 567
        if (r.IsProperty()) {
545
          return GetPropertyWithFailedAccessCheck(receiver,
546
                                                  &r,
547
                                                  name,
548
                                                  attributes);
568
          return GetPropertyWithFailedAccessCheck(
569
              object, receiver, &r, name, attributes);
549 570
        }
550 571
        break;
551 572
      }
......
556 577

  
557 578
  // No accessible property found.
558 579
  *attributes = ABSENT;
559
  Heap* heap = name->GetHeap();
560
  Isolate* isolate = heap->isolate();
561
  isolate->ReportFailedAccessCheck(this, v8::ACCESS_GET);
562
  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
563
  return heap->undefined_value();
580
  isolate->ReportFailedAccessCheck(*object, v8::ACCESS_GET);
581
  RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
582
  return isolate->factory()->undefined_value();
564 583
}
565 584

  
566 585

  
......
643 662
}
644 663

  
645 664

  
646
Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object,
647
                                               LookupResult* result,
648
                                               Handle<Object> value) {
649
  CALL_HEAP_FUNCTION(object->GetIsolate(),
650
                     object->SetNormalizedProperty(result, *value),
651
                     Object);
652
}
653

  
654

  
655
MaybeObject* JSObject::SetNormalizedProperty(LookupResult* result,
656
                                             Object* value) {
657
  ASSERT(!HasFastProperties());
658
  if (IsGlobalObject()) {
659
    PropertyCell* cell = PropertyCell::cast(
660
        property_dictionary()->ValueAt(result->GetDictionaryEntry()));
661
    MaybeObject* maybe_type = cell->SetValueInferType(value);
662
    if (maybe_type->IsFailure()) return maybe_type;
665
void JSObject::SetNormalizedProperty(Handle<JSObject> object,
666
                                     LookupResult* result,
667
                                     Handle<Object> value) {
668
  ASSERT(!object->HasFastProperties());
669
  NameDictionary* property_dictionary = object->property_dictionary();
670
  if (object->IsGlobalObject()) {
671
    Handle<PropertyCell> cell(PropertyCell::cast(
672
        property_dictionary->ValueAt(result->GetDictionaryEntry())));
673
    PropertyCell::SetValueInferType(cell, value);
663 674
  } else {
664
    property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
675
    property_dictionary->ValueAtPut(result->GetDictionaryEntry(), *value);
665 676
  }
666
  return value;
667 677
}
668 678

  
669 679

  
670
Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object,
671
                                               Handle<Name> key,
672
                                               Handle<Object> value,
673
                                               PropertyDetails details) {
674
  CALL_HEAP_FUNCTION(object->GetIsolate(),
675
                     object->SetNormalizedProperty(*key, *value, details),
676
                     Object);
680
// TODO(mstarzinger): Temporary wrapper until handlified.
681
static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
682
                                                Handle<Name> name,
683
                                                Handle<Object> value,
684
                                                PropertyDetails details) {
685
  CALL_HEAP_FUNCTION(dict->GetIsolate(),
686
                     dict->Add(*name, *value, details),
687
                     NameDictionary);
677 688
}
678 689

  
679 690

  
680
MaybeObject* JSObject::SetNormalizedProperty(Name* name,
681
                                             Object* value,
682
                                             PropertyDetails details) {
683
  ASSERT(!HasFastProperties());
684
  int entry = property_dictionary()->FindEntry(name);
691
void JSObject::SetNormalizedProperty(Handle<JSObject> object,
692
                                     Handle<Name> name,
693
                                     Handle<Object> value,
694
                                     PropertyDetails details) {
695
  ASSERT(!object->HasFastProperties());
696
  Handle<NameDictionary> property_dictionary(object->property_dictionary());
697

  
698
  if (!name->IsUniqueName()) {
699
    name = object->GetIsolate()->factory()->InternalizedStringFromString(
700
        Handle<String>::cast(name));
701
  }
702

  
703
  int entry = property_dictionary->FindEntry(*name);
685 704
  if (entry == NameDictionary::kNotFound) {
686
    Object* store_value = value;
687
    if (IsGlobalObject()) {
688
      Heap* heap = name->GetHeap();
689
      MaybeObject* maybe_store_value = heap->AllocatePropertyCell(value);
690
      if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
691
    }
692
    Object* dict;
693
    { MaybeObject* maybe_dict =
694
          property_dictionary()->Add(name, store_value, details);
695
      if (!maybe_dict->ToObject(&dict)) return maybe_dict;
705
    Handle<Object> store_value = value;
706
    if (object->IsGlobalObject()) {
707
      store_value = object->GetIsolate()->factory()->NewPropertyCell(value);
696 708
    }
697
    set_properties(NameDictionary::cast(dict));
698
    return value;
709

  
710
    property_dictionary =
711
        NameDictionaryAdd(property_dictionary, name, store_value, details);
712
    object->set_properties(*property_dictionary);
713
    return;
699 714
  }
700 715

  
701
  PropertyDetails original_details = property_dictionary()->DetailsAt(entry);
716
  PropertyDetails original_details = property_dictionary->DetailsAt(entry);
702 717
  int enumeration_index;
703 718
  // Preserve the enumeration index unless the property was deleted.
704 719
  if (original_details.IsDeleted()) {
705
    enumeration_index = property_dictionary()->NextEnumerationIndex();
706
    property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1);
720
    enumeration_index = property_dictionary->NextEnumerationIndex();
721
    property_dictionary->SetNextEnumerationIndex(enumeration_index + 1);
707 722
  } else {
708 723
    enumeration_index = original_details.dictionary_index();
709 724
    ASSERT(enumeration_index > 0);
......
712 727
  details = PropertyDetails(
713 728
      details.attributes(), details.type(), enumeration_index);
714 729

  
715
  if (IsGlobalObject()) {
716
    PropertyCell* cell =
717
        PropertyCell::cast(property_dictionary()->ValueAt(entry));
718
    MaybeObject* maybe_type = cell->SetValueInferType(value);
719
    if (maybe_type->IsFailure()) return maybe_type;
730
  if (object->IsGlobalObject()) {
731
    Handle<PropertyCell> cell(
732
        PropertyCell::cast(property_dictionary->ValueAt(entry)));
733
    PropertyCell::SetValueInferType(cell, value);
720 734
    // Please note we have to update the property details.
721
    property_dictionary()->DetailsAtPut(entry, details);
735
    property_dictionary->DetailsAtPut(entry, details);
722 736
  } else {
723
    property_dictionary()->SetEntry(entry, name, value, details);
737
    property_dictionary->SetEntry(entry, *name, *value, details);
724 738
  }
725
  return value;
726 739
}
727 740

  
728 741

  
......
733 746
}
734 747

  
735 748

  
736
static void CellSetValueInferType(Handle<PropertyCell> cell,
737
                                  Handle<Object> value) {
738
  CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), cell->SetValueInferType(*value));
739
}
740

  
741

  
742 749
Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
743 750
                                                  Handle<Name> name,
744 751
                                                  DeleteMode mode) {
......
761 768
        object->set_map(*new_map);
762 769
      }
763 770
      Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
764
      CellSetValueInferType(cell, isolate->factory()->the_hole_value());
771
      Handle<Object> value = isolate->factory()->the_hole_value();
772
      PropertyCell::SetValueInferType(cell, value);
765 773
      dictionary->DetailsAtPut(entry, details.AsDeleted());
766 774
    } else {
767 775
      Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate);
......
817 825
}
818 826

  
819 827

  
828
// TODO(yangguo): handlify this and get rid of.
820 829
MaybeObject* Object::GetProperty(Object* receiver,
821 830
                                 LookupResult* result,
822 831
                                 Name* name,
823 832
                                 PropertyAttributes* attributes) {
824
  // Make sure that the top context does not change when doing
825
  // callbacks or interceptor calls.
826
  AssertNoContextChangeWithHandleScope ncc;
827

  
828 833
  Isolate* isolate = name->GetIsolate();
829 834
  Heap* heap = isolate->heap();
830 835

  
836
#ifdef DEBUG
837
  // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon
838
  // as this method has been fully handlified.
839
  HandleScope scope(isolate);
840
#endif
841

  
842
  // Make sure that the top context does not change when doing
843
  // callbacks or interceptor calls.
844
  AssertNoContextChange ncc(isolate);
845

  
831 846
  // Traverse the prototype chain from the current object (this) to
832 847
  // the holder and check for access rights. This avoids traversing the
833 848
  // objects more than once in case of interceptors, because the
......
849 864
        // property from the current object, we still check that we have
850 865
        // access to it.
851 866
        JSObject* checked = JSObject::cast(current);
852
        if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
853
          return checked->GetPropertyWithFailedAccessCheck(receiver,
854
                                                           result,
855
                                                           name,
856
                                                           attributes);
867
        if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
868
          HandleScope scope(isolate);
869
          Handle<Object> value = JSObject::GetPropertyWithFailedAccessCheck(
870
              handle(checked, isolate),
871
              handle(receiver, isolate),
872
              result,
873
              handle(name, isolate),
874
              attributes);
875
          RETURN_IF_EMPTY_HANDLE(isolate, value);
876
          return *value;
857 877
        }
858 878
      }
859 879
      // Stop traversing the chain once we reach the last object in the
......
884 904
    }
885 905
    case CONSTANT:
886 906
      return result->GetConstant();
887
    case CALLBACKS:
888
      return result->holder()->GetPropertyWithCallback(
889
          receiver, result->GetCallbackObject(), name);
907
    case CALLBACKS: {
908
      HandleScope scope(isolate);
909
      Handle<Object> value = JSObject::GetPropertyWithCallback(
910
          handle(result->holder(), isolate),
911
          handle(receiver, isolate),
912
          handle(result->GetCallbackObject(), isolate),
913
          handle(name, isolate));
914
      RETURN_IF_EMPTY_HANDLE(isolate, value);
915
      return *value;
916
    }
890 917
    case HANDLER:
891 918
      return result->proxy()->GetPropertyWithHandler(receiver, name);
892
    case INTERCEPTOR:
893
      return result->holder()->GetPropertyWithInterceptor(
894
          receiver, name, attributes);
919
    case INTERCEPTOR: {
920
      HandleScope scope(isolate);
921
      Handle<Object> value = JSObject::GetPropertyWithInterceptor(
922
          handle(result->holder(), isolate),
923
          handle(receiver, isolate),
924
          handle(name, isolate),
925
          attributes);
926
      RETURN_IF_EMPTY_HANDLE(isolate, value);
927
      return *value;
928
    }
895 929
    case TRANSITION:
896 930
    case NONEXISTENT:
897 931
      UNREACHABLE();
......
1026 1060
  if (IsNumber() && other->IsNumber()) {
1027 1061
    double this_value = Number();
1028 1062
    double other_value = other->Number();
1029
    return (this_value == other_value) ||
1030
        (std::isnan(this_value) && std::isnan(other_value));
1063
    bool equal = this_value == other_value;
1064
    // SameValue(NaN, NaN) is true.
1065
    if (!equal) return std::isnan(this_value) && std::isnan(other_value);
1066
    // SameValue(0.0, -0.0) is false.
1067
    return (this_value != 0) || ((1 / this_value) == (1 / other_value));
1031 1068
  }
1032 1069
  if (IsString() && other->IsString()) {
1033 1070
    return String::cast(this)->Equals(String::cast(other));
......
1167 1204
  // Externalizing twice leaks the external resource, so it's
1168 1205
  // prohibited by the API.
1169 1206
  ASSERT(!this->IsExternalString());
1170
#ifdef DEBUG
1207
#ifdef ENABLE_SLOW_ASSERTS
1171 1208
  if (FLAG_enable_slow_asserts) {
1172 1209
    // Assert that the resource and the string are equivalent.
1173 1210
    ASSERT(static_cast<size_t>(this->length()) == resource->length());
......
1224 1261

  
1225 1262

  
1226 1263
bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) {
1227
#ifdef DEBUG
1264
#ifdef ENABLE_SLOW_ASSERTS
1228 1265
  if (FLAG_enable_slow_asserts) {
1229 1266
    // Assert that the resource and the string are equivalent.
1230 1267
    ASSERT(static_cast<size_t>(this->length()) == resource->length());
......
1709 1746
    case FIXED_ARRAY_TYPE:
1710 1747
      FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1711 1748
      break;
1749
    case CONSTANT_POOL_ARRAY_TYPE:
1750
      reinterpret_cast<ConstantPoolArray*>(this)->ConstantPoolIterateBody(v);
1751
      break;
1712 1752
    case FIXED_DOUBLE_ARRAY_TYPE:
1713 1753
      break;
1714 1754
    case JS_OBJECT_TYPE:
......
1871 1911
}
1872 1912

  
1873 1913

  
1874
MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
1875
                                               Name* name,
1876
                                               Object* value,
1877
                                               int field_index,
1878
                                               Representation representation) {
1914
// TODO(mstarzinger): Temporary wrapper until handlified.
1915
static Handle<Object> NewStorageFor(Isolate* isolate,
1916
                                    Handle<Object> object,
1917
                                    Representation representation) {
1918
  Heap* heap = isolate->heap();
1919
  CALL_HEAP_FUNCTION(isolate,
1920
                     object->AllocateNewStorageFor(heap, representation),
1921
                     Object);
1922
}
1923

  
1924

  
1925
void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
1926
                                       Handle<Map> new_map,
1927
                                       Handle<Name> name,
1928
                                       Handle<Object> value,
1929
                                       int field_index,
1930
                                       Representation representation) {
1931
  Isolate* isolate = object->GetIsolate();
1932

  
1879 1933
  // This method is used to transition to a field. If we are transitioning to a
1880 1934
  // double field, allocate new storage.
1881
  Object* storage;
1882
  MaybeObject* maybe_storage =
1883
      value->AllocateNewStorageFor(GetHeap(), representation);
1884
  if (!maybe_storage->To(&storage)) return maybe_storage;
1935
  Handle<Object> storage = NewStorageFor(isolate, value, representation);
1885 1936

  
1886
  if (map()->unused_property_fields() == 0) {
1937
  if (object->map()->unused_property_fields() == 0) {
1887 1938
    int new_unused = new_map->unused_property_fields();
1888
    FixedArray* values;
1889
    MaybeObject* maybe_values =
1890
        properties()->CopySize(properties()->length() + new_unused + 1);
1891
    if (!maybe_values->To(&values)) return maybe_values;
1939
    Handle<FixedArray> properties(object->properties());
1940
    Handle<FixedArray> values = isolate->factory()->CopySizeFixedArray(
1941
        properties, properties->length() + new_unused + 1);
1942
    object->set_properties(*values);
1943
  }
1944

  
1945
  object->set_map(*new_map);
1946
  object->FastPropertyAtPut(field_index, *storage);
1947
}
1892 1948

  
1893
    set_properties(values);
1949

  
1950
static MaybeObject* CopyAddFieldDescriptor(Map* map,
1951
                                           Name* name,
1952
                                           int index,
1953
                                           PropertyAttributes attributes,
1954
                                           Representation representation,
1955
                                           TransitionFlag flag) {
1956
  Map* new_map;
1957
  FieldDescriptor new_field_desc(name, index, attributes, representation);
1958
  MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag);
1959
  if (!maybe_map->To(&new_map)) return maybe_map;
1960
  int unused_property_fields = map->unused_property_fields() - 1;
1961
  if (unused_property_fields < 0) {
1962
    unused_property_fields += JSObject::kFieldsAdded;
1894 1963
  }
1964
  new_map->set_unused_property_fields(unused_property_fields);
1965
  return new_map;
1966
}
1895 1967

  
1896
  set_map(new_map);
1897 1968

  
1898
  FastPropertyAtPut(field_index, storage);
1899
  return value;
1969
static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map,
1970
                                          Handle<Name> name,
1971
                                          int index,
1972
                                          PropertyAttributes attributes,
1973
                                          Representation representation,
1974
                                          TransitionFlag flag) {
1975
  CALL_HEAP_FUNCTION(map->GetIsolate(),
1976
                     CopyAddFieldDescriptor(
1977
                         *map, *name, index, attributes, representation, flag),
1978
                     Map);
1900 1979
}
1901 1980

  
1902 1981

  
1903
MaybeObject* JSObject::AddFastProperty(Name* name,
1904
                                       Object* value,
1905
                                       PropertyAttributes attributes,
1906
                                       StoreFromKeyed store_mode,
1907
                                       ValueType value_type,
1908
                                       TransitionFlag flag) {
1909
  ASSERT(!IsJSGlobalProxy());
1982
void JSObject::AddFastProperty(Handle<JSObject> object,
1983
                               Handle<Name> name,
1984
                               Handle<Object> value,
1985
                               PropertyAttributes attributes,
1986
                               StoreFromKeyed store_mode,
1987
                               ValueType value_type,
1988
                               TransitionFlag flag) {
1989
  ASSERT(!object->IsJSGlobalProxy());
1910 1990
  ASSERT(DescriptorArray::kNotFound ==
1911
         map()->instance_descriptors()->Search(
1912
             name, map()->NumberOfOwnDescriptors()));
1991
         object->map()->instance_descriptors()->Search(
1992
             *name, object->map()->NumberOfOwnDescriptors()));
1913 1993

  
1914 1994
  // Normalize the object if the name is an actual name (not the
1915 1995
  // hidden strings) and is not a real identifier.
1916 1996
  // Normalize the object if it will have too many fast properties.
1917
  Isolate* isolate = GetHeap()->isolate();
1918
  if (!name->IsCacheable(isolate) || TooManyFastProperties(store_mode)) {
1919
    MaybeObject* maybe_failure =
1920
        NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1921
    if (maybe_failure->IsFailure()) return maybe_failure;
1922
    return AddSlowProperty(name, value, attributes);
1997
  Isolate* isolate = object->GetIsolate();
1998
  if (!name->IsCacheable(isolate) ||
1999
      object->TooManyFastProperties(store_mode)) {
2000
    NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2001
    AddSlowProperty(object, name, value, attributes);
2002
    return;
1923 2003
  }
1924 2004

  
1925 2005
  // Compute the new index for new field.
1926
  int index = map()->NextFreePropertyIndex();
2006
  int index = object->map()->NextFreePropertyIndex();
1927 2007

  
1928 2008
  // Allocate new instance descriptors with (name, index) added
1929
  if (IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
2009
  if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED;
1930 2010
  Representation representation = value->OptimalRepresentation(value_type);
2011
  Handle<Map> new_map = CopyAddFieldDescriptor(
2012
      handle(object->map()), name, index, attributes, representation, flag);
1931 2013

  
1932
  FieldDescriptor new_field(name, index, attributes, representation);
1933

  
1934
  Map* new_map;
1935
  MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&new_field, flag);
1936
  if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2014
  AddFastPropertyUsingMap(object, new_map, name, value, index, representation);
2015
}
1937 2016

  
1938
  int unused_property_fields = map()->unused_property_fields() - 1;
1939
  if (unused_property_fields < 0) {
1940
    unused_property_fields += kFieldsAdded;
1941
  }
1942
  new_map->set_unused_property_fields(unused_property_fields);
1943 2017

  
1944
  return AddFastPropertyUsingMap(new_map, name, value, index, representation);
2018
static MaybeObject* CopyAddConstantDescriptor(Map* map,
2019
                                              Name* name,
2020
                                              Object* value,
2021
                                              PropertyAttributes attributes,
2022
                                              TransitionFlag flag) {
2023
  ConstantDescriptor new_constant_desc(name, value, attributes);
2024
  return map->CopyAddDescriptor(&new_constant_desc, flag);
1945 2025
}
1946 2026

  
1947 2027

  
1948
MaybeObject* JSObject::AddConstantProperty(
1949
    Name* name,
1950
    Object* constant,
1951
    PropertyAttributes attributes,
1952
    TransitionFlag initial_flag) {
1953
  // Allocate new instance descriptors with (name, constant) added
1954
  ConstantDescriptor d(name, constant, attributes);
2028
static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map,
2029
                                             Handle<Name> name,
2030
                                             Handle<Object> value,
2031
                                             PropertyAttributes attributes,
2032
                                             TransitionFlag flag) {
2033
  CALL_HEAP_FUNCTION(map->GetIsolate(),
2034
                     CopyAddConstantDescriptor(
2035
                         *map, *name, *value, attributes, flag),
2036
                     Map);
2037
}
1955 2038

  
2039

  
2040
void JSObject::AddConstantProperty(Handle<JSObject> object,
2041
                                   Handle<Name> name,
2042
                                   Handle<Object> constant,
2043
                                   PropertyAttributes attributes,
2044
                                   TransitionFlag initial_flag) {
1956 2045
  TransitionFlag flag =
1957 2046
      // Do not add transitions to global objects.
1958
      (IsGlobalObject() ||
2047
      (object->IsGlobalObject() ||
1959 2048
      // Don't add transitions to special properties with non-trivial
1960 2049
      // attributes.
1961 2050
       attributes != NONE)
1962 2051
      ? OMIT_TRANSITION
1963 2052
      : initial_flag;
1964 2053

  
1965
  Map* new_map;
1966
  MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag);
1967
  if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2054
  // Allocate new instance descriptors with (name, constant) added.
2055
  Handle<Map> new_map = CopyAddConstantDescriptor(
2056
      handle(object->map()), name, constant, attributes, flag);
1968 2057

  
1969
  set_map(new_map);
1970
  return constant;
2058
  object->set_map(*new_map);
1971 2059
}
1972 2060

  
1973 2061

  
1974
// Add property in slow mode
1975
MaybeObject* JSObject::AddSlowProperty(Name* name,
1976
                                       Object* value,
1977
                                       PropertyAttributes attributes) {
1978
  ASSERT(!HasFastProperties());
1979
  NameDictionary* dict = property_dictionary();
1980
  Object* store_value = value;
1981
  if (IsGlobalObject()) {
2062
void JSObject::AddSlowProperty(Handle<JSObject> object,
2063
                               Handle<Name> name,
2064
                               Handle<Object> value,
2065
                               PropertyAttributes attributes) {
2066
  ASSERT(!object->HasFastProperties());
2067
  Isolate* isolate = object->GetIsolate();
2068
  Handle<NameDictionary> dict(object->property_dictionary());
2069
  if (object->IsGlobalObject()) {
1982 2070
    // In case name is an orphaned property reuse the cell.
1983
    int entry = dict->FindEntry(name);
2071
    int entry = dict->FindEntry(*name);
1984 2072
    if (entry != NameDictionary::kNotFound) {
1985
      store_value = dict->ValueAt(entry);
1986
      MaybeObject* maybe_type =
1987
          PropertyCell::cast(store_value)->SetValueInferType(value);
1988
      if (maybe_type->IsFailure()) return maybe_type;
2073
      Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
2074
      PropertyCell::SetValueInferType(cell, value);
1989 2075
      // Assign an enumeration index to the property and update
1990 2076
      // SetNextEnumerationIndex.
1991 2077
      int index = dict->NextEnumerationIndex();
1992 2078
      PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
1993 2079
      dict->SetNextEnumerationIndex(index + 1);
1994
      dict->SetEntry(entry, name, store_value, details);
1995
      return value;
1996
    }
1997
    Heap* heap = GetHeap();
1998
    { MaybeObject* maybe_store_value =
1999
          heap->AllocatePropertyCell(value);
2000
      if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
2080
      dict->SetEntry(entry, *name, *cell, details);
2081
      return;
2001 2082
    }
2002
    MaybeObject* maybe_type =
2003
        PropertyCell::cast(store_value)->SetValueInferType(value);
2004
    if (maybe_type->IsFailure()) return maybe_type;
2083
    Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(value);
2084
    PropertyCell::SetValueInferType(cell, value);
2085
    value = cell;
2005 2086
  }
2006 2087
  PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
2007
  Object* result;
2008
  { MaybeObject* maybe_result = dict->Add(name, store_value, details);
2009
    if (!maybe_result->ToObject(&result)) return maybe_result;
2010
  }
2011
  if (dict != result) set_properties(NameDictionary::cast(result));
2012
  return value;
2088
  Handle<NameDictionary> result = NameDictionaryAdd(dict, name, value, details);
2089
  if (*dict != *result) object->set_properties(*result);
2013 2090
}
2014 2091

  
2015 2092

  
2016
MaybeObject* JSObject::AddProperty(Name* name,
2017
                                   Object* value,
2018
                                   PropertyAttributes attributes,
2019
                                   StrictModeFlag strict_mode,
2020
                                   JSReceiver::StoreFromKeyed store_mode,
2021
                                   ExtensibilityCheck extensibility_check,
2022
                                   ValueType value_type,
2023
                                   StoreMode mode,
2024
                                   TransitionFlag transition_flag) {
2025
  ASSERT(!IsJSGlobalProxy());
2026
  Map* map_of_this = map();
2027
  Heap* heap = GetHeap();
2028
  Isolate* isolate = heap->isolate();
2029
  MaybeObject* result;
2093
Handle<Object> JSObject::AddProperty(Handle<JSObject> object,
2094
                                     Handle<Name> name,
2095
                                     Handle<Object> value,
2096
                                     PropertyAttributes attributes,
2097
                                     StrictModeFlag strict_mode,
2098
                                     JSReceiver::StoreFromKeyed store_mode,
2099
                                     ExtensibilityCheck extensibility_check,
2100
                                     ValueType value_type,
2101
                                     StoreMode mode,
2102
                                     TransitionFlag transition_flag) {
2103
  ASSERT(!object->IsJSGlobalProxy());
2104
  Isolate* isolate = object->GetIsolate();
2105

  
2106
  if (!name->IsUniqueName()) {
2107
    name = isolate->factory()->InternalizedStringFromString(
2108
        Handle<String>::cast(name));
2109
  }
2110

  
2030 2111
  if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
2031
      !map_of_this->is_extensible()) {
2112
      !object->map()->is_extensible()) {
2032 2113
    if (strict_mode == kNonStrictMode) {
2033 2114
      return value;
2034 2115
    } else {
2035
      Handle<Object> args[1] = {Handle<Name>(name)};
2036
      return isolate->Throw(
2037
          *isolate->factory()->NewTypeError("object_not_extensible",
2038
                                            HandleVector(args, 1)));
2116
      Handle<Object> args[1] = { name };
2117
      Handle<Object> error = isolate->factory()->NewTypeError(
2118
          "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2119
      isolate->Throw(*error);
2120
      return Handle<Object>();
2039 2121
    }
2040 2122
  }
2041 2123

  
2042
  if (HasFastProperties()) {
2124
  if (object->HasFastProperties()) {
2043 2125
    // Ensure the descriptor array does not get too big.
2044
    if (map_of_this->NumberOfOwnDescriptors() <
2126
    if (object->map()->NumberOfOwnDescriptors() <
2045 2127
        DescriptorArray::kMaxNumberOfDescriptors) {
2046 2128
      // TODO(verwaest): Support other constants.
2047 2129
      // if (mode == ALLOW_AS_CONSTANT &&
2048 2130
      //     !value->IsTheHole() &&
2049 2131
      //     !value->IsConsString()) {
2050 2132
      if (value->IsJSFunction()) {
2051
        result = AddConstantProperty(name, value, attributes, transition_flag);
2133
        AddConstantProperty(object, name, value, attributes, transition_flag);
2052 2134
      } else {
2053
        result = AddFastProperty(
2054
            name, value, attributes, store_mode, value_type, transition_flag);
2135
        AddFastProperty(object, name, value, attributes, store_mode,
2136
                        value_type, transition_flag);
2055 2137
      }
2056 2138
    } else {
2057 2139
      // Normalize the object to prevent very large instance descriptors.
2058 2140
      // This eliminates unwanted N^2 allocation and lookup behavior.
2059
      Object* obj;
2060
      MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2061
      if (!maybe->To(&obj)) return maybe;
2062
      result = AddSlowProperty(name, value, attributes);
2141
      NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2142
      AddSlowProperty(object, name, value, attributes);
2063 2143
    }
2064 2144
  } else {
2065
    result = AddSlowProperty(name, value, attributes);
2145
    AddSlowProperty(object, name, value, attributes);
2066 2146
  }
2067 2147

  
2068
  Handle<Object> hresult;
2069
  if (!result->ToHandle(&hresult, isolate)) return result;
2070

  
2071
  if (FLAG_harmony_observation && map()->is_observed()) {
2072
    EnqueueChangeRecord(handle(this, isolate),
2073
                        "new",
2074
                        handle(name, isolate),
2075
                        handle(heap->the_hole_value(), isolate));
2148
  if (FLAG_harmony_observation &&
2149
      object->map()->is_observed() &&
2150
      *name != isolate->heap()->hidden_string()) {
2151
    Handle<Object> old_value = isolate->factory()->the_hole_value();
2152
    EnqueueChangeRecord(object, "new", name, old_value);
2076 2153
  }
2077 2154

  
2078
  return *hresult;
2155
  return value;
2079 2156
}
2080 2157

  
2081 2158

  
......
2115 2192
}
2116 2193

  
2117 2194

  
2118
MaybeObject* JSObject::SetPropertyPostInterceptor(
2119
    Name* name,
2120
    Object* value,
2195
Handle<Object> JSObject::SetPropertyPostInterceptor(
2196
    Handle<JSObject> object,
2197
    Handle<Name> name,
2198
    Handle<Object> value,
2121 2199
    PropertyAttributes attributes,
2122
    StrictModeFlag strict_mode,
2123
    StoreMode mode) {
2200
    StrictModeFlag strict_mode) {
2124 2201
  // Check local property, ignore interceptor.
2125
  LookupResult result(GetIsolate());
2126
  LocalLookupRealNamedProperty(name, &result);
2127
  if (!result.IsFound()) map()->LookupTransition(this, name, &result);
2202
  LookupResult result(object->GetIsolate());
2203
  object->LocalLookupRealNamedProperty(*name, &result);
2204
  if (!result.IsFound()) {
2205
    object->map()->LookupTransition(*object, *name, &result);
2206
  }
2128 2207
  if (result.IsFound()) {
2129 2208
    // An existing property or a map transition was found. Use set property to
2130 2209
    // handle all these cases.
2131
    return SetProperty(&result, name, value, attributes, strict_mode);
2210
    return SetPropertyForResult(object, &result, name, value, attributes,
2211
                                strict_mode, MAY_BE_STORE_FROM_KEYED);
2132 2212
  }
2133 2213
  bool done = false;
2134
  MaybeObject* result_object =
2135
      SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
2214
  Handle<Object> result_object = SetPropertyViaPrototypes(
2215
      object, name, value, attributes, strict_mode, &done);
2136 2216
  if (done) return result_object;
2137 2217
  // Add a new real property.
2138
  return AddProperty(name, value, attributes, strict_mode,
2139
                     MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
2140
                     OPTIMAL_REPRESENTATION, mode);
2218
  return AddProperty(object, name, value, attributes, strict_mode);
2141 2219
}
2142 2220

  
2143 2221

  
2144
MaybeObject* JSObject::ReplaceSlowProperty(Name* name,
2145
                                           Object* value,
2146
                                           PropertyAttributes attributes) {
2147
  NameDictionary* dictionary = property_dictionary();
2148
  int old_index = dictionary->FindEntry(name);
2222
static void ReplaceSlowProperty(Handle<JSObject> object,
2223
                                Handle<Name> name,
2224
                                Handle<Object> value,
2225
                                PropertyAttributes attributes) {
2226
  NameDictionary* dictionary = object->property_dictionary();
2227
  int old_index = dictionary->FindEntry(*name);
2149 2228
  int new_enumeration_index = 0;  // 0 means "Use the next available index."
2150 2229
  if (old_index != -1) {
2151 2230
    // All calls to ReplaceSlowProperty have had all transitions removed.
......
2153 2232
  }
2154 2233

  
2155 2234
  PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2156
  return SetNormalizedProperty(name, value, new_details);
2235
  JSObject::SetNormalizedProperty(object, name, value, new_details);
2157 2236
}
2158 2237

  
2159 2238

  
......
2219 2298
      MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
2220 2299
    }
2221 2300
  }
2301

  
2302
  // The array may not be moved during GC,
2303
  // and size has to be adjusted nevertheless.
2304
  HeapProfiler* profiler = heap->isolate()->heap_profiler();
2305
  if (profiler->is_tracking_allocations()) {
2306
    profiler->UpdateObjectSizeEvent(elms->address(), elms->Size());
2307
  }
2222 2308
}
2223 2309

  
2224 2310

  
......
2275 2361
//     to temporarily store the inobject properties.
2276 2362
//   * If there are properties left in the backing store, install the backing
2277 2363
//     store.
2278
MaybeObject* JSObject::MigrateToMap(Map* new_map) {
2279
  Heap* heap = GetHeap();
2280
  Map* old_map = map();
2364
void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
2365
  Isolate* isolate = object->GetIsolate();
2366
  Handle<Map> old_map(object->map());
2281 2367
  int number_of_fields = new_map->NumberOfFields();
2282 2368
  int inobject = new_map->inobject_properties();
2283 2369
  int unused = new_map->unused_property_fields();
2284 2370

  
2285
  // Nothing to do if no functions were converted to fields.
2371
  // Nothing to do if no functions were converted to fields and no smis were
2372
  // converted to doubles.
2286 2373
  if (!old_map->InstancesNeedRewriting(
2287
          new_map, number_of_fields, inobject, unused)) {
2288
    set_map(new_map);
2289
    return this;
2374
          *new_map, number_of_fields, inobject, unused)) {
2375
    object->set_map(*new_map);
2376
    return;
2290 2377
  }
2291 2378

  
2292 2379
  int total_size = number_of_fields + unused;
2293 2380
  int external = total_size - inobject;
2294
  FixedArray* array;
2295
  MaybeObject* maybe_array = heap->AllocateFixedArray(total_size);
2296
  if (!maybe_array->To(&array)) return maybe_array;
2381
  Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size);
2297 2382

  
2298
  DescriptorArray* old_descriptors = old_map->instance_descriptors();
2299
  DescriptorArray* new_descriptors = new_map->instance_descriptors();
2383
  Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2384
  Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors());
2300 2385
  int descriptors = new_map->NumberOfOwnDescriptors();
2301 2386

  
2302 2387
  for (int i = 0; i < descriptors; i++) {
......
2309 2394
    }
2310 2395
    ASSERT(old_details.type() == CONSTANT ||
2311 2396
           old_details.type() == FIELD);
2312
    Object* value = old_details.type() == CONSTANT
2397
    Object* raw_value = old_details.type() == CONSTANT
2313 2398
        ? old_descriptors->GetValue(i)
2314
        : RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2399
        : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2400
    Handle<Object> value(raw_value, isolate);
2315 2401
    if (FLAG_track_double_fields &&
2316 2402
        !old_details.representation().IsDouble() &&
2317 2403
        details.representation().IsDouble()) {
2318
      if (old_details.representation().IsNone()) value = Smi::FromInt(0);
2319
      // Objects must be allocated in the old object space, since the
2320
      // overall number of HeapNumbers needed for the conversion might
2321
      // exceed the capacity of new space, and we would fail repeatedly
2322
      // trying to migrate the instance.
2323
      MaybeObject* maybe_storage =
2324
          value->AllocateNewStorageFor(heap, details.representation(), TENURED);
2325
      if (!maybe_storage->To(&value)) return maybe_storage;
2404
      if (old_details.representation().IsNone()) {
2405
        value = handle(Smi::FromInt(0), isolate);
2406
      }
2407
      value = NewStorageFor(isolate, value, details.representation());
2326 2408
    }
2327 2409
    ASSERT(!(FLAG_track_double_fields &&
2328 2410
             details.representation().IsDouble() &&
2329 2411
             value->IsSmi()));
2330 2412
    int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2331 2413
    if (target_index < 0) target_index += total_size;
2332
    array->set(target_index, value);
2414
    array->set(target_index, *value);
2333 2415
  }
2334 2416

  
2335
  // From here on we cannot fail anymore.
2417
  // From here on we cannot fail and we shouldn't GC anymore.
2418
  DisallowHeapAllocation no_allocation;
2336 2419

  
2337 2420
  // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2338 2421
  // avoid overwriting |one_pointer_filler_map|.
2339 2422
  int limit = Min(inobject, number_of_fields);
2340 2423
  for (int i = 0; i < limit; i++) {
2341
    FastPropertyAtPut(i, array->get(external + i));
2424
    object->FastPropertyAtPut(i, array->get(external + i));
2342 2425
  }
2343 2426

  
2344 2427
  // Create filler object past the new instance size.
2345 2428
  int new_instance_size = new_map->instance_size();
2346 2429
  int instance_size_delta = old_map->instance_size() - new_instance_size;
2347 2430
  ASSERT(instance_size_delta >= 0);
2348
  Address address = this->address() + new_instance_size;
2349
  heap->CreateFillerObjectAt(address, instance_size_delta);
2431
  Address address = object->address() + new_instance_size;
2432
  isolate->heap()->CreateFillerObjectAt(address, instance_size_delta);
2350 2433

  
2351 2434
  // If there are properties in the new backing store, trim it to the correct
2352 2435
  // size and install the backing store into the object.
2353 2436
  if (external > 0) {
2354
    RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject);
2355
    set_properties(array);
2437
    RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject);
2438
    object->set_properties(*array);
2356 2439
  }
2357 2440

  
2358
  set_map(new_map);
2359

  
2360
  return this;
2441
  object->set_map(*new_map);
2361 2442
}
2362 2443

  
2363 2444

  
2364
MaybeObject* JSObject::GeneralizeFieldRepresentation(
2365
    int modify_index,
2366
    Representation new_representation,
2367
    StoreMode store_mode) {
2368
  Map* new_map;
2369
  MaybeObject* maybe_new_map = map()->GeneralizeRepresentation(
2370
      modify_index, new_representation, store_mode);
2371
  if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2372
  if (map() == new_map) return this;
2445
Handle<TransitionArray> Map::AddTransition(Handle<Map> map,
2446
                                           Handle<Name> key,
2447
                                           Handle<Map> target,
2448
                                           SimpleTransitionFlag flag) {
2449
  CALL_HEAP_FUNCTION(map->GetIsolate(),
2450
                     map->AddTransition(*key, *target, flag),
2451
                     TransitionArray);
2452
}
2453

  
2373 2454

  
2374
  return MigrateToMap(new_map);
2455
void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2456
                                             int modify_index,
2457
                                             Representation new_representation,
2458
                                             StoreMode store_mode) {
2459
  Handle<Map> new_map = Map::GeneralizeRepresentation(
2460
      handle(object->map()), modify_index, new_representation, store_mode);
2461
  if (object->map() == *new_map) return;
2462
  return MigrateToMap(object, new_map);
2375 2463
}
2376 2464

  
2377 2465

  
......
2385 2473
}
2386 2474

  
2387 2475

  
2388
MaybeObject* Map::CopyGeneralizeAllRepresentations(
2389
    int modify_index,
2390
    StoreMode store_mode,
2391
    PropertyAttributes attributes,
2392
    const char* reason) {
2393
  Map* new_map;
2394
  MaybeObject* maybe_map = this->Copy();
2395
  if (!maybe_map->To(&new_map)) return maybe_map;
2476
Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map,
2477
                                                  int modify_index,
2478
                                                  StoreMode store_mode,
2479
                                                  PropertyAttributes attributes,
2480
                                                  const char* reason) {
2481
  Handle<Map> new_map = Copy(map);
2396 2482

  
2397 2483
  DescriptorArray* descriptors = new_map->instance_descriptors();
2398 2484
  descriptors->InitializeRepresentations(Representation::Tagged());
......
2414 2500
  }
2415 2501

  
2416 2502
  if (FLAG_trace_generalization) {
2417
    PrintGeneralization(stdout, reason, modify_index,
2503
    map->PrintGeneralization(stdout, reason, modify_index,
2418 2504
                        new_map->NumberOfOwnDescriptors(),
2419 2505
                        new_map->NumberOfOwnDescriptors(),
2420 2506
                        details.type() == CONSTANT && store_mode == FORCE_FIELD,
......
2562 2648
// - If |updated| == |split_map|, |updated| is in the expected state. Return it.
2563 2649
// - Otherwise, invalidate the outdated transition target from |updated|, and
2564 2650
//   replace its transition tree with a new branch for the updated descriptors.
2565
MaybeObject* Map::GeneralizeRepresentation(int modify_index,
2566
                                           Representation new_representation,
2567
                                           StoreMode store_mode) {
2568
  Map* old_map = this;
2569
  DescriptorArray* old_descriptors = old_map->instance_descriptors();
2651
Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
2652
                                          int modify_index,
2653
                                          Representation new_representation,
2654
                                          StoreMode store_mode) {
2655
  Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
2570 2656
  PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
2571 2657
  Representation old_representation = old_details.representation();
2572 2658

  
......
2582 2668
  }
2583 2669

  
2584 2670
  int descriptors = old_map->NumberOfOwnDescriptors();
2585
  Map* root_map = old_map->FindRootMap();
2671
  Handle<Map> root_map(old_map->FindRootMap());
2586 2672

  
2587 2673
  // Check the state of the root map.
2588
  if (!old_map->EquivalentToForTransition(root_map)) {
2589
    return CopyGeneralizeAllRepresentations(
2590
        modify_index, store_mode, old_details.attributes(), "not equivalent");
2674
  if (!old_map->EquivalentToForTransition(*root_map)) {
2675
    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2676
        old_details.attributes(), "not equivalent");
2591 2677
  }
2592 2678

  
2593 2679
  int verbatim = root_map->NumberOfOwnDescriptors();
2594 2680

  
2595 2681
  if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) {
2596
    return CopyGeneralizeAllRepresentations(
2597
        modify_index, store_mode,
2682
    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2598 2683
        old_details.attributes(), "root modification");
2599 2684
  }
2600 2685

  
2601
  Map* updated = root_map->FindUpdatedMap(
2602
      verbatim, descriptors, old_descriptors);
2603
  if (updated == NULL) {
2604
    return CopyGeneralizeAllRepresentations(
2605
        modify_index, store_mode, old_details.attributes(), "incompatible");
2686
  Map* raw_updated = root_map->FindUpdatedMap(
2687
      verbatim, descriptors, *old_descriptors);
2688
  if (raw_updated == NULL) {
2689
    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
2690
        old_details.attributes(), "incompatible");
2606 2691
  }
2607 2692

  
2608
  DescriptorArray* updated_descriptors = updated->instance_descriptors();
2693
  Handle<Map> updated(raw_updated);
2694
  Handle<DescriptorArray> updated_descriptors(updated->instance_descriptors());
2609 2695

  
2610 2696
  int valid = updated->NumberOfOwnDescriptors();
2611 2697

  
2612 2698
  // Directly change the map if the target map is more general. Ensure that the
2613 2699
  // target type of the modify_index is a FIELD, unless we are migrating.
2614 2700
  if (updated_descriptors->IsMoreGeneralThan(
2615
          verbatim, valid, descriptors, old_descriptors) &&
2701
          verbatim, valid, descriptors, *old_descriptors) &&
2616 2702
      (store_mode == ALLOW_AS_CONSTANT ||
2617 2703
       updated_descriptors->GetDetails(modify_index).type() == FIELD)) {
2618 2704
    Representation updated_representation =
......
2620 2706
    if (new_representation.fits_into(updated_representation)) return updated;
2621 2707
  }
2622 2708

  
2623
  DescriptorArray* new_descriptors;
2624
  MaybeObject* maybe_descriptors = updated_descriptors->Merge(
2625
      verbatim, valid, descriptors, modify_index, store_mode, old_descriptors);
2626
  if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
2709
  Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
2710
      updated_descriptors, verbatim, valid, descriptors, modify_index,
2711
      store_mode, old_descriptors);
2627 2712
  ASSERT(store_mode == ALLOW_AS_CONSTANT ||
2628 2713
         new_descriptors->GetDetails(modify_index).type() == FIELD);
2629 2714

  
......
2635 2720
    new_descriptors->SetRepresentation(modify_index, updated_representation);
2636 2721
  }
2637 2722

  
2638
  Map* split_map = root_map->FindLastMatchMap(
2639
      verbatim, descriptors, new_descriptors);
2723
  Handle<Map> split_map(root_map->FindLastMatchMap(
2724
      verbatim, descriptors, *new_descriptors));
2640 2725

  
2641 2726
  int split_descriptors = split_map->NumberOfOwnDescriptors();
2642 2727
  // This is shadowed by |updated_descriptors| being more general than
......
2645 2730

  
2646 2731
  int descriptor = split_descriptors;
2647 2732
  split_map->DeprecateTarget(
2648
      old_descriptors->GetKey(descriptor), new_descriptors);
2733
      old_descriptors->GetKey(descriptor), *new_descriptors);
2649 2734

  
2650 2735
  if (FLAG_trace_generalization) {
2651
    PrintGeneralization(
2736
    old_map->PrintGeneralization(
2652 2737
        stdout, "", modify_index, descriptor, descriptors,
2653 2738
        old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2654 2739
            store_mode == FORCE_FIELD,
2655 2740
        old_representation, updated_representation);
2656 2741
  }
2657 2742

  
2658
  Map* new_map = split_map;
2659 2743
  // Add missing transitions.
2744
  Handle<Map> new_map = split_map;
2660 2745
  for (; descriptor < descriptors; descriptor++) {
2661
    MaybeObject* maybe_map = new_map->CopyInstallDescriptors(
2662
        descriptor, new_descriptors);
2663
    if (!maybe_map->To(&new_map)) {
2664
      // Create a handle for the last created map to ensure it stays alive
2665
      // during GC. Its descriptor array is too large, but it will be
2666
      // overwritten during retry anyway.
2667
      Handle<Map>(new_map);
2668
      return maybe_map;
2669
    }
2746
    new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2670 2747
    new_map->set_migration_target(true);
2671 2748
  }
2672 2749

  
......
2675 2752
}
2676 2753

  
2677 2754

  
2678
Map* Map::CurrentMapForDeprecated() {
2755
// Generalize the representation of all FIELD descriptors.
2756
Handle<Map> Map::GeneralizeAllFieldRepresentations(
2757
    Handle<Map> map,
2758
    Representation new_representation) {
2759
  Handle<DescriptorArray> descriptors(map->instance_descriptors());
2760
  for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
2761
    PropertyDetails details = descriptors->GetDetails(i);
2762
    if (details.type() == FIELD) {
2763
      map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
2764
    }
2765
  }
2766
  return map;
2767
}
2768

  
2769

  
2770
Map* Map::CurrentMapForDeprecated() {
2679 2771
  DisallowHeapAllocation no_allocation;
2680 2772
  if (!is_deprecated()) return this;
2681 2773

  
......
2703 2795
}
2704 2796

  
2705 2797

  
2706
MaybeObject* JSObject::SetPropertyWithInterceptor(
2707
    Name* name,
2708
    Object* value,
2798
Handle<Object> JSObject::SetPropertyWithInterceptor(
2799
    Handle<JSObject> object,
2800
    Handle<Name> name,
2801
    Handle<Object> value,
2709 2802
    PropertyAttributes attributes,
2710 2803
    StrictModeFlag strict_mode) {
2711 2804
  // TODO(rossberg): Support symbols in the API.
2712 2805
  if (name->IsSymbol()) return value;
2713
  Isolate* isolate = GetIsolate();
2714
  HandleScope scope(isolate);
2715
  Handle<JSObject> this_handle(this);
2716
  Handle<String> name_handle(String::cast(name));
2717
  Handle<Object> value_handle(value, isolate);
2718
  Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2806
  Isolate* isolate = object->GetIsolate();
2807
  Handle<String> name_string = Handle<String>::cast(name);
2808
  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
2719 2809
  if (!interceptor->setter()->IsUndefined()) {
2720
    LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
2721
    PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
2810
    LOG(isolate,
2811
        ApiNamedPropertyAccess("interceptor-named-set", *object, *name));
2812
    PropertyCallbackArguments args(
2813
        isolate, interceptor->data(), *object, *object);
2722 2814
    v8::NamedPropertySetterCallback setter =
2723 2815
        v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
2724
    Handle<Object> value_unhole(value->IsTheHole() ?
2725
                                isolate->heap()->undefined_value() :
2726
                                value,
2727
                                isolate);
2816
    Handle<Object> value_unhole = value->IsTheHole()
2817
        ? Handle<Object>(isolate->factory()->undefined_value()) : value;
2728 2818
    v8::Handle<v8::Value> result = args.Call(setter,
2729
                                             v8::Utils::ToLocal(name_handle),
2819
                                             v8::Utils::ToLocal(name_string),
2730 2820
                                             v8::Utils::ToLocal(value_unhole));
2731
    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2732
    if (!result.IsEmpty()) return *value_handle;
2821
    RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2822
    if (!result.IsEmpty()) return value;
2733 2823
  }
2734
  MaybeObject* raw_result =
2735
      this_handle->SetPropertyPostInterceptor(*name_handle,
2736
                                              *value_handle,
2737
                                              attributes,
2738
                                              strict_mode);
2739
  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2740
  return raw_result;
2824
  Handle<Object> result =
2825
      SetPropertyPostInterceptor(object, name, value, attributes, strict_mode);
2826
  RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2827
  return result;
2741 2828
}
2742 2829

  
2743 2830

  
2744 2831
Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
2745
                                       Handle<Name> key,
2832
                                       Handle<Name> name,
2746 2833
                                       Handle<Object> value,
2747 2834
                                       PropertyAttributes attributes,
2748
                                       StrictModeFlag strict_mode) {
2749
  CALL_HEAP_FUNCTION(object->GetIsolate(),
2750
                     object->SetProperty(*key, *value, attributes, strict_mode),
2751
                     Object);
2752
}
2753

  
2754

  
2755
MaybeObject* JSReceiver::SetPropertyOrFail(
2756
    Handle<JSReceiver> object,
2757
    Handle<Name> key,
2758
    Handle<Object> value,
2759
    PropertyAttributes attributes,
2760
    StrictModeFlag strict_mode,
2761
    JSReceiver::StoreFromKeyed store_mode) {
2762
  CALL_HEAP_FUNCTION_PASS_EXCEPTION(
2763
      object->GetIsolate(),
2764
      object->SetProperty(*key, *value, attributes, strict_mode, store_mode));
2765
}
2766

  
2767

  
2768
MaybeObject* JSReceiver::SetProperty(Name* name,
2769
                                     Object* value,
2770
                                     PropertyAttributes attributes,
2771
                                     StrictModeFlag strict_mode,
2772
                                     JSReceiver::StoreFromKeyed store_mode) {
2773
  LookupResult result(GetIsolate());
2774
  LocalLookup(name, &result, true);
2835
                                       StrictModeFlag strict_mode,
2836
                                       StoreFromKeyed store_mode) {
2837
  LookupResult result(object->GetIsolate());
2838
  object->LocalLookup(*name, &result, true);
2775 2839
  if (!result.IsFound()) {
2776
    map()->LookupTransition(JSObject::cast(this), name, &result);
2840
    object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
2777 2841
  }
2778
  return SetProperty(&result, name, value, attributes, strict_mode, store_mode);
2842
  return SetProperty(object, &result, name, value, attributes, strict_mode,
2843
                     store_mode);
2779 2844
}
2780 2845

  
2781 2846

  
2782
MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
2783
                                               Name* name,
2784
                                               Object* value,
2785
                                               JSObject* holder,
2786
                                               StrictModeFlag strict_mode) {
2787
  Isolate* isolate = GetIsolate();
2788
  HandleScope scope(isolate);
2847
Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
2848
                                                 Handle<Object> structure,
2849
                                                 Handle<Name> name,
2850
                                                 Handle<Object> value,
2851
                                                 Handle<JSObject> holder,
2852
                                                 StrictModeFlag strict_mode) {
2853
  Isolate* isolate = object->GetIsolate();
2789 2854

  
2790 2855
  // We should never get here to initialize a const with the hole
2791 2856
  // value since a const declaration would conflict with the setter.
2792 2857
  ASSERT(!value->IsTheHole());
2793
  Handle<Object> value_handle(value, isolate);
2794 2858

  
2795 2859
  // To accommodate both the old and the new api we switch on the
2796 2860
  // data structure used to store the callbacks.  Eventually foreign
......
2798 2862
  if (structure->IsForeign()) {
2799 2863
    AccessorDescriptor* callback =
2800 2864
        reinterpret_cast<AccessorDescriptor*>(
2801
            Foreign::cast(structure)->foreign_address());
2802
    MaybeObject* obj = (callback->setter)(
2803
        isolate, this,  value, callback->data);
2804
    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff