factory.cc 80.4 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
#include "src/factory.h"
6

7
#include "src/allocation-site-scopes.h"
8
#include "src/base/bits.h"
9 10 11
#include "src/conversions.h"
#include "src/isolate-inl.h"
#include "src/macro-assembler.h"
12

13 14
namespace v8 {
namespace internal {
15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

template<typename T>
Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->Allocate(*map, space),
      T);
}


template<typename T>
Handle<T> Factory::New(Handle<Map> map,
                       AllocationSpace space,
                       Handle<AllocationSite> allocation_site) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->Allocate(*map, space, *allocation_site),
      T);
}


37 38 39 40 41 42 43 44 45 46
Handle<HeapObject> Factory::NewFillerObject(int size,
                                            bool double_align,
                                            AllocationSpace space) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateFillerObject(size, double_align, space),
      HeapObject);
}


47 48 49 50
Handle<Box> Factory::NewBox(Handle<Object> value) {
  Handle<Box> result = Handle<Box>::cast(NewStruct(BOX_TYPE));
  result->set_value(*value);
  return result;
51 52 53
}


54 55 56 57 58 59 60 61 62
Handle<PrototypeInfo> Factory::NewPrototypeInfo() {
  Handle<PrototypeInfo> result =
      Handle<PrototypeInfo>::cast(NewStruct(PROTOTYPE_INFO_TYPE));
  result->set_prototype_users(WeakFixedArray::Empty());
  result->set_validity_cell(Smi::FromInt(0));
  return result;
}


63 64 65 66
Handle<Oddball> Factory::NewOddball(Handle<Map> map,
                                    const char* to_string,
                                    Handle<Object> to_number,
                                    byte kind) {
67
  Handle<Oddball> oddball = New<Oddball>(map, OLD_SPACE);
68 69 70 71 72
  Oddball::Initialize(isolate(), oddball, to_string, to_number, kind);
  return oddball;
}


73
Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
74
  DCHECK(0 <= size);
75 76 77 78
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateFixedArray(size, pretenure),
      FixedArray);
79 80 81
}


82 83
Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
                                                   PretenureFlag pretenure) {
84
  DCHECK(0 <= size);
85 86
  CALL_HEAP_FUNCTION(
      isolate(),
87 88 89
      isolate()->heap()->AllocateFixedArrayWithFiller(size,
                                                      pretenure,
                                                      *the_hole_value()),
90
      FixedArray);
91 92 93
}


94 95 96 97 98 99 100 101
Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateUninitializedFixedArray(size),
      FixedArray);
}


102
Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size,
103
                                                    PretenureFlag pretenure) {
104
  DCHECK(0 <= size);
105 106 107
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure),
108
      FixedArrayBase);
109 110 111
}


112
Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(
113 114
    int size,
    PretenureFlag pretenure) {
115
  DCHECK(0 <= size);
116 117 118 119 120 121 122
  Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure);
  if (size > 0) {
    Handle<FixedDoubleArray> double_array =
        Handle<FixedDoubleArray>::cast(array);
    for (int i = 0; i < size; ++i) {
      double_array->set_the_hole(i);
    }
123 124 125 126 127
  }
  return array;
}


128
Handle<ConstantPoolArray> Factory::NewConstantPoolArray(
129
    const ConstantPoolArray::NumberOfEntries& small) {
130
  DCHECK(small.total_count() > 0);
131 132
  CALL_HEAP_FUNCTION(
      isolate(),
133 134 135 136 137 138 139 140
      isolate()->heap()->AllocateConstantPoolArray(small),
      ConstantPoolArray);
}


Handle<ConstantPoolArray> Factory::NewExtendedConstantPoolArray(
    const ConstantPoolArray::NumberOfEntries& small,
    const ConstantPoolArray::NumberOfEntries& extended) {
141 142
  DCHECK(small.total_count() > 0);
  DCHECK(extended.total_count() > 0);
143 144 145
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateExtendedConstantPoolArray(small, extended),
146 147 148 149
      ConstantPoolArray);
}


150
Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
151
  return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity);
152 153 154 155
}


Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
156
  return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity);
157 158 159
}


160
Handle<AccessorPair> Factory::NewAccessorPair() {
161 162 163 164 165
  Handle<AccessorPair> accessors =
      Handle<AccessorPair>::cast(NewStruct(ACCESSOR_PAIR_TYPE));
  accessors->set_getter(*the_hole_value(), SKIP_WRITE_BARRIER);
  accessors->set_setter(*the_hole_value(), SKIP_WRITE_BARRIER);
  return accessors;
166 167 168
}


169
Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() {
170 171 172 173
  Handle<TypeFeedbackInfo> info =
      Handle<TypeFeedbackInfo>::cast(NewStruct(TYPE_FEEDBACK_INFO_TYPE));
  info->initialize_storage();
  return info;
174 175 176
}


177 178
// Internalized strings are created in the old generation (data space).
Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) {
179 180
  Utf8StringKey key(string, isolate()->heap()->HashSeed());
  return InternalizeStringWithKey(&key);
181 182
}

183

184 185
// Internalized strings are created in the old generation (data space).
Handle<String> Factory::InternalizeString(Handle<String> string) {
186 187
  if (string->IsInternalizedString()) return string;
  return StringTable::LookupString(isolate(), string);
188 189
}

190

191
Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
192 193
  OneByteStringKey key(string, isolate()->heap()->HashSeed());
  return InternalizeStringWithKey(&key);
194 195
}

196

197 198
Handle<String> Factory::InternalizeOneByteString(
    Handle<SeqOneByteString> string, int from, int length) {
199
  SeqOneByteSubStringKey key(string, from, length);
200
  return InternalizeStringWithKey(&key);
201 202 203
}


204
Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) {
205 206 207 208 209 210 211
  TwoByteStringKey key(string, isolate()->heap()->HashSeed());
  return InternalizeStringWithKey(&key);
}


template<class StringTableKey>
Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
212
  return StringTable::LookupKey(isolate(), key);
213 214
}

215

216 217 218
MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
                                                  PretenureFlag pretenure) {
  int length = string.length();
219
  if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
220 221
  Handle<SeqOneByteString> result;
  ASSIGN_RETURN_ON_EXCEPTION(
222
      isolate(),
223 224
      result,
      NewRawOneByteString(string.length(), pretenure),
225
      String);
226 227 228 229 230 231 232

  DisallowHeapAllocation no_gc;
  // Copy the characters into the new object.
  CopyChars(SeqOneByteString::cast(*result)->GetChars(),
            string.start(),
            length);
  return result;
233 234
}

235 236
MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
                                               PretenureFlag pretenure) {
237 238 239 240 241 242 243 244 245
  // Check for ASCII first since this is the common case.
  const char* start = string.start();
  int length = string.length();
  int non_ascii_start = String::NonAsciiStart(start, length);
  if (non_ascii_start >= length) {
    // If the string is ASCII, we do not need to convert the characters
    // since UTF8 is backwards compatible with ASCII.
    return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure);
  }
246

247
  // Non-ASCII and we need to decode.
248 249 250 251
  Access<UnicodeCache::Utf8Decoder>
      decoder(isolate()->unicode_cache()->utf8_decoder());
  decoder->Reset(string.start() + non_ascii_start,
                 length - non_ascii_start);
252
  int utf16_length = static_cast<int>(decoder->Utf16Length());
253
  DCHECK(utf16_length > 0);
254 255 256 257 258
  // Allocate string.
  Handle<SeqTwoByteString> result;
  ASSIGN_RETURN_ON_EXCEPTION(
      isolate(), result,
      NewRawTwoByteString(non_ascii_start + utf16_length, pretenure),
259
      String);
260
  // Copy ASCII portion.
261 262 263 264 265 266 267 268
  uint16_t* data = result->GetChars();
  const char* ascii_data = string.start();
  for (int i = 0; i < non_ascii_start; i++) {
    *data++ = *ascii_data++;
  }
  // Now write the remainder.
  decoder->WriteUtf16(data, utf16_length);
  return result;
269 270 271
}


272 273
MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
                                                  PretenureFlag pretenure) {
274 275 276
  int length = string.length();
  const uc16* start = string.start();
  if (String::IsOneByte(start, length)) {
277
    if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
    Handle<SeqOneByteString> result;
    ASSIGN_RETURN_ON_EXCEPTION(
        isolate(),
        result,
        NewRawOneByteString(length, pretenure),
        String);
    CopyChars(result->GetChars(), start, length);
    return result;
  } else {
    Handle<SeqTwoByteString> result;
    ASSIGN_RETURN_ON_EXCEPTION(
        isolate(),
        result,
        NewRawTwoByteString(length, pretenure),
        String);
    CopyChars(result->GetChars(), start, length);
    return result;
  }
296 297 298
}


299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str,
                                                      int chars,
                                                      uint32_t hash_field) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateInternalizedStringFromUtf8(
          str, chars, hash_field),
      String);
}


MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString(
      Vector<const uint8_t> str,
      uint32_t hash_field) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateOneByteInternalizedString(str, hash_field),
      String);
}


320 321 322 323 324 325 326 327 328 329 330
MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedSubString(
    Handle<SeqOneByteString> string, int offset, int length,
    uint32_t hash_field) {
  CALL_HEAP_FUNCTION(
      isolate(), isolate()->heap()->AllocateOneByteInternalizedString(
                     Vector<const uint8_t>(string->GetChars() + offset, length),
                     hash_field),
      String);
}


331 332 333 334 335 336 337 338 339 340 341
MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString(
      Vector<const uc16> str,
      uint32_t hash_field) {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateTwoByteInternalizedString(str, hash_field),
      String);
}


Handle<String> Factory::NewInternalizedStringImpl(
342
    Handle<String> string, int chars, uint32_t hash_field) {
343 344
  CALL_HEAP_FUNCTION(
      isolate(),
345 346
      isolate()->heap()->AllocateInternalizedStringImpl(
          *string, chars, hash_field),
347 348 349 350 351 352 353 354 355 356 357 358
      String);
}


MaybeHandle<Map> Factory::InternalizedStringMapForString(
    Handle<String> string) {
  // If the string is in new space it cannot be used as internalized.
  if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>();

  // Find the corresponding internalized string map for strings.
  switch (string->map()->instance_type()) {
    case STRING_TYPE: return internalized_string_map();
359 360
    case ONE_BYTE_STRING_TYPE:
      return one_byte_internalized_string_map();
361
    case EXTERNAL_STRING_TYPE: return external_internalized_string_map();
362 363
    case EXTERNAL_ONE_BYTE_STRING_TYPE:
      return external_one_byte_internalized_string_map();
364 365 366 367
    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
      return external_internalized_string_with_one_byte_data_map();
    case SHORT_EXTERNAL_STRING_TYPE:
      return short_external_internalized_string_map();
368 369
    case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
      return short_external_one_byte_internalized_string_map();
370 371 372 373 374 375 376
    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
      return short_external_internalized_string_with_one_byte_data_map();
    default: return MaybeHandle<Map>();  // No match found.
  }
}


377 378
MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString(
    int length, PretenureFlag pretenure) {
379
  if (length > String::kMaxLength || length < 0) {
380
    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString);
381
  }
382 383
  CALL_HEAP_FUNCTION(
      isolate(),
384
      isolate()->heap()->AllocateRawOneByteString(length, pretenure),
385
      SeqOneByteString);
386 387 388
}


389 390
MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString(
    int length, PretenureFlag pretenure) {
391
  if (length > String::kMaxLength || length < 0) {
392
    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString);
393
  }
394 395 396
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateRawTwoByteString(length, pretenure),
397
      SeqTwoByteString);
398 399 400
}


401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) {
  if (code <= String::kMaxOneByteCharCodeU) {
    {
      DisallowHeapAllocation no_allocation;
      Object* value = single_character_string_cache()->get(code);
      if (value != *undefined_value()) {
        return handle(String::cast(value), isolate());
      }
    }
    uint8_t buffer[1];
    buffer[0] = static_cast<uint8_t>(code);
    Handle<String> result =
        InternalizeOneByteString(Vector<const uint8_t>(buffer, 1));
    single_character_string_cache()->set(code, *result);
    return result;
  }
417
  DCHECK(code <= String::kMaxUtf16CodeUnitU);
418 419 420 421

  Handle<SeqTwoByteString> result = NewRawTwoByteString(1).ToHandleChecked();
  result->SeqTwoByteStringSet(0, static_cast<uint16_t>(code));
  return result;
422 423 424
}


425 426 427 428 429 430 431 432 433 434 435 436 437
// Returns true for a character in a range.  Both limits are inclusive.
static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
  // This makes uses of the the unsigned wraparound.
  return character - from <= to - from;
}


static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
                                                          uint16_t c1,
                                                          uint16_t c2) {
  // Numeric strings have a different hash algorithm not known by
  // LookupTwoCharsStringIfExists, so we skip this step for such strings.
  if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) {
438 439 440 441
    Handle<String> result;
    if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2).
        ToHandle(&result)) {
      return result;
442 443 444 445 446 447 448
    }
  }

  // Now we know the length is 2, we might as well make use of that fact
  // when building the new string.
  if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
    // We can do this.
449 450
    DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU +
                                      1));  // because of this.
451 452
    Handle<SeqOneByteString> str =
        isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
453 454 455 456 457
    uint8_t* dest = str->GetChars();
    dest[0] = static_cast<uint8_t>(c1);
    dest[1] = static_cast<uint8_t>(c2);
    return str;
  } else {
458 459
    Handle<SeqTwoByteString> str =
        isolate->factory()->NewRawTwoByteString(2).ToHandleChecked();
460 461 462 463 464
    uc16* dest = str->GetChars();
    dest[0] = c1;
    dest[1] = c2;
    return str;
  }
465 466 467
}


468 469 470 471 472 473 474 475 476 477 478 479
template<typename SinkChar, typename StringType>
Handle<String> ConcatStringContent(Handle<StringType> result,
                                   Handle<String> first,
                                   Handle<String> second) {
  DisallowHeapAllocation pointer_stays_valid;
  SinkChar* sink = result->GetChars();
  String::WriteToFlat(*first, sink, 0, first->length());
  String::WriteToFlat(*second, sink + first->length(), 0, second->length());
  return result;
}


480 481
MaybeHandle<String> Factory::NewConsString(Handle<String> left,
                                           Handle<String> right) {
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
  int left_length = left->length();
  if (left_length == 0) return right;
  int right_length = right->length();
  if (right_length == 0) return left;

  int length = left_length + right_length;

  if (length == 2) {
    uint16_t c1 = left->Get(0);
    uint16_t c2 = right->Get(0);
    return MakeOrFindTwoCharacterString(isolate(), c1, c2);
  }

  // Make sure that an out of memory exception is thrown if the length
  // of the new cons string is too large.
  if (length > String::kMaxLength || length < 0) {
498
    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
499 500 501 502 503 504 505 506
  }

  bool left_is_one_byte = left->IsOneByteRepresentation();
  bool right_is_one_byte = right->IsOneByteRepresentation();
  bool is_one_byte = left_is_one_byte && right_is_one_byte;
  bool is_one_byte_data_in_two_byte_string = false;
  if (!is_one_byte) {
    // At least one of the strings uses two-byte representation so we
507 508
    // can't use the fast case code for short one-byte strings below, but
    // we can try to save memory if all chars actually fit in one-byte.
509 510 511
    is_one_byte_data_in_two_byte_string =
        left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars();
    if (is_one_byte_data_in_two_byte_string) {
512
      isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment();
513 514 515 516 517 518 519
    }
  }

  // If the resulting string is small make a flat string.
  if (length < ConsString::kMinLength) {
    // Note that neither of the two inputs can be a slice because:
    STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
520 521
    DCHECK(left->IsFlat());
    DCHECK(right->IsFlat());
522

523
    STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength);
524
    if (is_one_byte) {
525 526
      Handle<SeqOneByteString> result =
          NewRawOneByteString(length).ToHandleChecked();
527 528 529
      DisallowHeapAllocation no_gc;
      uint8_t* dest = result->GetChars();
      // Copy left part.
530 531 532 533
      const uint8_t* src =
          left->IsExternalString()
              ? Handle<ExternalOneByteString>::cast(left)->GetChars()
              : Handle<SeqOneByteString>::cast(left)->GetChars();
534 535 536
      for (int i = 0; i < left_length; i++) *dest++ = src[i];
      // Copy right part.
      src = right->IsExternalString()
537 538
                ? Handle<ExternalOneByteString>::cast(right)->GetChars()
                : Handle<SeqOneByteString>::cast(right)->GetChars();
539 540 541 542 543
      for (int i = 0; i < right_length; i++) *dest++ = src[i];
      return result;
    }

    return (is_one_byte_data_in_two_byte_string)
544 545 546 547
        ? ConcatStringContent<uint8_t>(
            NewRawOneByteString(length).ToHandleChecked(), left, right)
        : ConcatStringContent<uc16>(
            NewRawTwoByteString(length).ToHandleChecked(), left, right);
548 549
  }

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
  return (is_one_byte || is_one_byte_data_in_two_byte_string)
             ? NewOneByteConsString(length, left, right)
             : NewTwoByteConsString(length, left, right);
}


MaybeHandle<String> Factory::NewOneByteConsString(int length,
                                                  Handle<String> left,
                                                  Handle<String> right) {
  return NewRawConsString(cons_one_byte_string_map(), length, left, right);
}


MaybeHandle<String> Factory::NewTwoByteConsString(int length,
                                                  Handle<String> left,
                                                  Handle<String> right) {
  return NewRawConsString(cons_string_map(), length, left, right);
}


MaybeHandle<String> Factory::NewRawConsString(Handle<Map> map, int length,
                                              Handle<String> left,
                                              Handle<String> right) {
  Handle<ConsString> result = New<ConsString>(map, NEW_SPACE);
574 575 576 577 578 579 580 581 582 583 584 585

  DisallowHeapAllocation no_gc;
  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);

  result->set_hash_field(String::kEmptyHashField);
  result->set_length(length);
  result->set_first(*left, mode);
  result->set_second(*right, mode);
  return result;
}


586
Handle<String> Factory::NewProperSubString(Handle<String> str,
587 588
                                           int begin,
                                           int end) {
589 590 591
#if VERIFY_HEAP
  if (FLAG_verify_heap) str->StringVerify();
#endif
592
  DCHECK(begin > 0 || end < str->length());
593

594 595
  str = String::Flatten(str);

596 597 598
  int length = end - begin;
  if (length <= 0) return empty_string();
  if (length == 1) {
599
    return LookupSingleCharacterStringFromCode(str->Get(begin));
600 601 602 603 604 605 606 607 608 609 610 611
  }
  if (length == 2) {
    // Optimization for 2-byte strings often used as keys in a decompression
    // dictionary.  Check whether we already have the string in the string
    // table to prevent creation of many unnecessary strings.
    uint16_t c1 = str->Get(begin);
    uint16_t c2 = str->Get(begin + 1);
    return MakeOrFindTwoCharacterString(isolate(), c1, c2);
  }

  if (!FLAG_string_slices || length < SlicedString::kMinLength) {
    if (str->IsOneByteRepresentation()) {
612 613
      Handle<SeqOneByteString> result =
          NewRawOneByteString(length).ToHandleChecked();
614 615 616 617 618
      uint8_t* dest = result->GetChars();
      DisallowHeapAllocation no_gc;
      String::WriteToFlat(*str, dest, begin, end);
      return result;
    } else {
619 620
      Handle<SeqTwoByteString> result =
          NewRawTwoByteString(length).ToHandleChecked();
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
      uc16* dest = result->GetChars();
      DisallowHeapAllocation no_gc;
      String::WriteToFlat(*str, dest, begin, end);
      return result;
    }
  }

  int offset = begin;

  if (str->IsSlicedString()) {
    Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
    str = Handle<String>(slice->parent(), isolate());
    offset += slice->offset();
  }

636
  DCHECK(str->IsSeqString() || str->IsExternalString());
637 638 639
  Handle<Map> map = str->IsOneByteRepresentation()
                        ? sliced_one_byte_string_map()
                        : sliced_string_map();
640
  Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE);
641 642 643 644 645 646

  slice->set_hash_field(String::kEmptyHashField);
  slice->set_length(length);
  slice->set_parent(*str);
  slice->set_offset(offset);
  return slice;
647 648 649
}


650 651
MaybeHandle<String> Factory::NewExternalStringFromOneByte(
    const ExternalOneByteString::Resource* resource) {
652 653
  size_t length = resource->length();
  if (length > static_cast<size_t>(String::kMaxLength)) {
654
    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
655 656
  }

657 658 659
  Handle<Map> map = external_one_byte_string_map();
  Handle<ExternalOneByteString> external_string =
      New<ExternalOneByteString>(map, NEW_SPACE);
660 661 662 663 664
  external_string->set_length(static_cast<int>(length));
  external_string->set_hash_field(String::kEmptyHashField);
  external_string->set_resource(resource);

  return external_string;
665 666 667
}


668
MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
669
    const ExternalTwoByteString::Resource* resource) {
670 671
  size_t length = resource->length();
  if (length > static_cast<size_t>(String::kMaxLength)) {
672
    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
  }

  // For small strings we check whether the resource contains only
  // one byte characters.  If yes, we use a different string map.
  static const size_t kOneByteCheckLengthLimit = 32;
  bool is_one_byte = length <= kOneByteCheckLengthLimit &&
      String::IsOneByte(resource->data(), static_cast<int>(length));
  Handle<Map> map = is_one_byte ?
      external_string_with_one_byte_data_map() : external_string_map();
  Handle<ExternalTwoByteString> external_string =
      New<ExternalTwoByteString>(map, NEW_SPACE);
  external_string->set_length(static_cast<int>(length));
  external_string->set_hash_field(String::kEmptyHashField);
  external_string->set_resource(resource);

  return external_string;
689 690 691
}


692 693 694 695 696 697 698 699
Handle<Symbol> Factory::NewSymbol() {
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateSymbol(),
      Symbol);
}


700
Handle<Symbol> Factory::NewPrivateSymbol() {
701 702 703
  Handle<Symbol> symbol = NewSymbol();
  symbol->set_is_private(true);
  return symbol;
704 705 706
}


707 708 709 710 711 712 713 714
Handle<Symbol> Factory::NewPrivateOwnSymbol() {
  Handle<Symbol> symbol = NewSymbol();
  symbol->set_is_private(true);
  symbol->set_is_own(true);
  return symbol;
}


715
Handle<Context> Factory::NewNativeContext() {
716 717 718 719
  Handle<FixedArray> array = NewFixedArray(Context::NATIVE_CONTEXT_SLOTS);
  array->set_map_no_write_barrier(*native_context_map());
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_js_array_maps(*undefined_value());
720
  DCHECK(context->IsNativeContext());
721
  return context;
722 723 724
}


725
Handle<Context> Factory::NewScriptContext(Handle<JSFunction> function,
726
                                          Handle<ScopeInfo> scope_info) {
727 728
  Handle<FixedArray> array =
      NewFixedArray(scope_info->ContextLength(), TENURED);
729
  array->set_map_no_write_barrier(*script_context_map());
730 731 732 733 734
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_closure(*function);
  context->set_previous(function->context());
  context->set_extension(*scope_info);
  context->set_global_object(function->context()->global_object());
735
  DCHECK(context->IsScriptContext());
736
  return context;
737 738 739
}


740
Handle<ScriptContextTable> Factory::NewScriptContextTable() {
741
  Handle<FixedArray> array = NewFixedArray(1);
742 743 744
  array->set_map_no_write_barrier(*script_context_table_map());
  Handle<ScriptContextTable> context_table =
      Handle<ScriptContextTable>::cast(array);
745 746 747 748 749
  context_table->set_used(0);
  return context_table;
}


750
Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
751 752 753 754 755 756 757
  Handle<FixedArray> array =
      NewFixedArray(scope_info->ContextLength(), TENURED);
  array->set_map_no_write_barrier(*module_context_map());
  // Instance link will be set later.
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_extension(Smi::FromInt(0));
  return context;
758 759 760
}


761
Handle<Context> Factory::NewFunctionContext(int length,
762
                                            Handle<JSFunction> function) {
763
  DCHECK(length >= Context::MIN_CONTEXT_SLOTS);
764 765 766 767 768 769 770 771
  Handle<FixedArray> array = NewFixedArray(length);
  array->set_map_no_write_barrier(*function_context_map());
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_closure(*function);
  context->set_previous(function->context());
  context->set_extension(Smi::FromInt(0));
  context->set_global_object(function->context()->global_object());
  return context;
772 773 774
}


775 776
Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function,
                                         Handle<Context> previous,
777 778
                                         Handle<String> name,
                                         Handle<Object> thrown_object) {
779 780 781 782 783 784 785 786 787 788
  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
  Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1);
  array->set_map_no_write_barrier(*catch_context_map());
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_closure(*function);
  context->set_previous(*previous);
  context->set_extension(*name);
  context->set_global_object(previous->global_object());
  context->set(Context::THROWN_OBJECT_INDEX, *thrown_object);
  return context;
789 790 791
}


792 793
Handle<Context> Factory::NewWithContext(Handle<JSFunction> function,
                                        Handle<Context> previous,
794 795 796 797 798 799 800 801 802
                                        Handle<JSReceiver> extension) {
  Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS);
  array->set_map_no_write_barrier(*with_context_map());
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_closure(*function);
  context->set_previous(*previous);
  context->set_extension(*extension);
  context->set_global_object(previous->global_object());
  return context;
803 804 805
}


806 807 808
Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function,
                                         Handle<Context> previous,
                                         Handle<ScopeInfo> scope_info) {
809 810 811 812 813 814 815 816 817
  Handle<FixedArray> array =
      NewFixedArrayWithHoles(scope_info->ContextLength());
  array->set_map_no_write_barrier(*block_context_map());
  Handle<Context> context = Handle<Context>::cast(array);
  context->set_closure(*function);
  context->set_previous(*previous);
  context->set_extension(*scope_info);
  context->set_global_object(previous->global_object());
  return context;
818 819 820
}


821
Handle<Struct> Factory::NewStruct(InstanceType type) {
822 823 824 825
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateStruct(type),
      Struct);
826 827 828
}


829
Handle<CodeCache> Factory::NewCodeCache() {
830 831 832 833 834
  Handle<CodeCache> code_cache =
      Handle<CodeCache>::cast(NewStruct(CODE_CACHE_TYPE));
  code_cache->set_default_cache(*empty_fixed_array(), SKIP_WRITE_BARRIER);
  code_cache->set_normal_type_cache(*undefined_value(), SKIP_WRITE_BARRIER);
  return code_cache;
835 836 837
}


838 839 840 841 842 843 844 845 846
Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry(
    int aliased_context_slot) {
  Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast(
      NewStruct(ALIASED_ARGUMENTS_ENTRY_TYPE));
  entry->set_aliased_context_slot(aliased_context_slot);
  return entry;
}


847 848 849 850
Handle<ExecutableAccessorInfo> Factory::NewExecutableAccessorInfo() {
  Handle<ExecutableAccessorInfo> info =
      Handle<ExecutableAccessorInfo>::cast(
          NewStruct(EXECUTABLE_ACCESSOR_INFO_TYPE));
851 852 853 854 855 856
  info->set_flag(0);  // Must clear the flag, it was initialized as undefined.
  return info;
}


Handle<Script> Factory::NewScript(Handle<String> source) {
857
  // Create and initialize script object.
858
  Heap* heap = isolate()->heap();
859 860
  Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
  script->set_source(*source);
861
  script->set_name(heap->undefined_value());
862
  script->set_id(isolate()->heap()->NextScriptId());
863 864
  script->set_line_offset(Smi::FromInt(0));
  script->set_column_offset(Smi::FromInt(0));
865
  script->set_context_data(heap->undefined_value());
866
  script->set_type(Smi::FromInt(Script::TYPE_NORMAL));
867
  script->set_wrapper(heap->undefined_value());
868 869
  script->set_line_ends(heap->undefined_value());
  script->set_eval_from_shared(heap->undefined_value());
870
  script->set_eval_from_instructions_offset(Smi::FromInt(0));
871
  script->set_flags(Smi::FromInt(0));
872

873 874 875 876
  return script;
}


877
Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) {
878
  CALL_HEAP_FUNCTION(isolate(),
879 880
                     isolate()->heap()->AllocateForeign(addr, pretenure),
                     Foreign);
881 882 883
}


884 885
Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) {
  return NewForeign((Address) desc, TENURED);
886 887 888
}


889
Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) {
890
  DCHECK(0 <= length);
891 892 893 894
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateByteArray(length, pretenure),
      ByteArray);
895 896 897
}


898 899 900 901
Handle<ExternalArray> Factory::NewExternalArray(int length,
                                                ExternalArrayType array_type,
                                                void* external_pointer,
                                                PretenureFlag pretenure) {
902
  DCHECK(0 <= length && length <= Smi::kMaxValue);
903 904 905 906 907 908 909
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateExternalArray(length,
                                               array_type,
                                               external_pointer,
                                               pretenure),
      ExternalArray);
910 911 912
}


913 914 915 916
Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray(
    int length,
    ExternalArrayType array_type,
    PretenureFlag pretenure) {
917
  DCHECK(0 <= length && length <= Smi::kMaxValue);
918 919 920 921 922 923 924 925 926
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateFixedTypedArray(length,
                                                 array_type,
                                                 pretenure),
      FixedTypedArrayBase);
}


927 928 929 930 931 932 933 934 935
Handle<Cell> Factory::NewCell(Handle<Object> value) {
  AllowDeferredHandleDereference convert_to_cell;
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateCell(*value),
      Cell);
}


936
Handle<PropertyCell> Factory::NewPropertyCell() {
937 938
  CALL_HEAP_FUNCTION(
      isolate(),
939
      isolate()->heap()->AllocatePropertyCell(),
940
      PropertyCell);
941 942 943
}


ulan@chromium.org's avatar
ulan@chromium.org committed
944 945 946 947 948 949 950
Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) {
  AllowDeferredHandleDereference convert_to_cell;
  CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateWeakCell(*value),
                     WeakCell);
}


951
Handle<AllocationSite> Factory::NewAllocationSite() {
952
  Handle<Map> map = allocation_site_map();
953
  Handle<AllocationSite> site = New<AllocationSite>(map, OLD_SPACE);
954 955 956 957 958 959
  site->Initialize();

  // Link the site
  site->set_weak_next(isolate()->heap()->allocation_sites_list());
  isolate()->heap()->set_allocation_sites_list(*site);
  return site;
960 961 962
}


963 964 965
Handle<Map> Factory::NewMap(InstanceType type,
                            int instance_size,
                            ElementsKind elements_kind) {
966 967
  CALL_HEAP_FUNCTION(
      isolate(),
968
      isolate()->heap()->AllocateMap(type, instance_size, elements_kind),
969
      Map);
970 971 972
}


973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) {
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyJSObject(*object, NULL),
                     JSObject);
}


Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
    Handle<JSObject> object,
    Handle<AllocationSite> site) {
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyJSObject(
                         *object,
                         site.is_null() ? NULL : *site),
                     JSObject);
}


991 992 993 994 995
Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array,
                                                  Handle<Map> map) {
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyFixedArrayWithMap(*array, *map),
                     FixedArray);
996 997 998
}


999
Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
1000
  CALL_HEAP_FUNCTION(isolate(),
1001
                     isolate()->heap()->CopyFixedArray(*array),
1002 1003 1004 1005
                     FixedArray);
}


1006 1007
Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray(
    Handle<FixedArray> array) {
1008
  DCHECK(isolate()->heap()->InNewSpace(*array));
1009
  CALL_HEAP_FUNCTION(isolate(),
1010
                     isolate()->heap()->CopyAndTenureFixedCOWArray(*array),
1011
                     FixedArray);
1012 1013 1014
}


1015 1016
Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
    Handle<FixedDoubleArray> array) {
1017 1018 1019
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyFixedDoubleArray(*array),
                     FixedDoubleArray);
1020 1021 1022
}


1023 1024
Handle<ConstantPoolArray> Factory::CopyConstantPoolArray(
    Handle<ConstantPoolArray> array) {
1025 1026 1027
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyConstantPoolArray(*array),
                     ConstantPoolArray);
1028 1029 1030
}


1031 1032
Handle<Object> Factory::NewNumber(double value,
                                  PretenureFlag pretenure) {
1033 1034 1035
  // We need to distinguish the minus zero value and this cannot be
  // done after conversion to int. Doing this by comparing bit
  // patterns is faster than using fpclassify() et al.
1036
  if (IsMinusZero(value)) return NewHeapNumber(-0.0, IMMUTABLE, pretenure);
1037

1038
  int int_value = FastD2IChecked(value);
1039 1040 1041 1042 1043
  if (value == int_value && Smi::IsValid(int_value)) {
    return handle(Smi::FromInt(int_value), isolate());
  }

  // Materialize the value in the heap.
1044
  return NewHeapNumber(value, IMMUTABLE, pretenure);
1045 1046 1047
}


1048 1049
Handle<Object> Factory::NewNumberFromInt(int32_t value,
                                         PretenureFlag pretenure) {
1050
  if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
1051 1052
  // Bypass NewNumber to avoid various redundant checks.
  return NewHeapNumber(FastI2D(value), IMMUTABLE, pretenure);
1053 1054 1055
}


1056
Handle<Object> Factory::NewNumberFromUint(uint32_t value,
1057 1058 1059 1060 1061
                                          PretenureFlag pretenure) {
  int32_t int32v = static_cast<int32_t>(value);
  if (int32v >= 0 && Smi::IsValid(int32v)) {
    return handle(Smi::FromInt(int32v), isolate());
  }
1062
  return NewHeapNumber(FastUI2D(value), IMMUTABLE, pretenure);
1063 1064 1065
}


1066
Handle<HeapNumber> Factory::NewHeapNumber(double value,
1067
                                          MutableMode mode,
1068 1069 1070
                                          PretenureFlag pretenure) {
  CALL_HEAP_FUNCTION(
      isolate(),
1071 1072
      isolate()->heap()->AllocateHeapNumber(value, mode, pretenure),
      HeapNumber);
1073 1074 1075
}


1076 1077
Handle<Object> Factory::NewTypeError(const char* message,
                                     Vector<Handle<Object> > args) {
1078
  return NewError("MakeTypeError", message, args);
1079 1080 1081
}


1082
Handle<Object> Factory::NewTypeError(Handle<String> message) {
1083 1084 1085 1086
  return NewError("$TypeError", message);
}


1087 1088
Handle<Object> Factory::NewRangeError(const char* message,
                                      Vector<Handle<Object> > args) {
1089
  return NewError("MakeRangeError", message, args);
1090 1091 1092
}


1093
Handle<Object> Factory::NewRangeError(Handle<String> message) {
1094 1095 1096 1097
  return NewError("$RangeError", message);
}


1098 1099
Handle<Object> Factory::NewSyntaxError(const char* message,
                                       Handle<JSArray> args) {
1100
  return NewError("MakeSyntaxError", message, args);
1101 1102 1103
}


1104
Handle<Object> Factory::NewSyntaxError(Handle<String> message) {
1105 1106 1107 1108
  return NewError("$SyntaxError", message);
}


1109 1110
Handle<Object> Factory::NewReferenceError(const char* message,
                                          Vector<Handle<Object> > args) {
1111
  return NewError("MakeReferenceError", message, args);
1112 1113 1114
}


1115 1116
Handle<Object> Factory::NewReferenceError(const char* message,
                                          Handle<JSArray> args) {
1117 1118 1119 1120
  return NewError("MakeReferenceError", message, args);
}


1121
Handle<Object> Factory::NewReferenceError(Handle<String> message) {
1122 1123 1124 1125
  return NewError("$ReferenceError", message);
}


1126 1127
Handle<Object> Factory::NewError(const char* maker, const char* message,
                                 Vector<Handle<Object> > args) {
1128
  // Instantiate a closeable HandleScope for EscapeFrom.
1129
  v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate()));
1130
  Handle<FixedArray> array = NewFixedArray(args.length());
1131 1132 1133
  for (int i = 0; i < args.length(); i++) {
    array->set(i, *args[i]);
  }
1134
  Handle<JSArray> object = NewJSArrayWithElements(array);
1135
  Handle<Object> result = NewError(maker, message, object);
1136 1137 1138 1139
  return result.EscapeFrom(&scope);
}


1140 1141
Handle<Object> Factory::NewEvalError(const char* message,
                                     Vector<Handle<Object> > args) {
1142
  return NewError("MakeEvalError", message, args);
1143 1144 1145
}


1146 1147
Handle<Object> Factory::NewError(const char* message,
                                 Vector<Handle<Object> > args) {
1148
  return NewError("MakeError", message, args);
1149 1150 1151
}


1152
Handle<String> Factory::EmergencyNewError(const char* message,
1153 1154 1155 1156 1157 1158 1159
                                          Handle<JSArray> args) {
  const int kBufferSize = 1000;
  char buffer[kBufferSize];
  size_t space = kBufferSize;
  char* p = &buffer[0];

  Vector<char> v(buffer, kBufferSize);
1160
  StrNCpy(v, message, space);
1161
  space -= Min(space, strlen(message));
1162 1163
  p = &buffer[kBufferSize] - space;

1164
  for (int i = 0; i < Smi::cast(args->length())->value(); i++) {
1165 1166 1167 1168
    if (space > 0) {
      *p++ = ' ';
      space--;
      if (space > 0) {
1169
        Handle<String> arg_str = Handle<String>::cast(
1170
            Object::GetElement(isolate(), args, i).ToHandleChecked());
1171
        SmartArrayPointer<char> arg = arg_str->ToCString();
1172
        Vector<char> v2(p, static_cast<int>(space));
1173
        StrNCpy(v2, arg.get(), space);
1174
        space -= Min(space, strlen(arg.get()));
1175 1176 1177 1178 1179 1180 1181 1182 1183
        p = &buffer[kBufferSize] - space;
      }
    }
  }
  if (space > 0) {
    *p = '\0';
  } else {
    buffer[kBufferSize - 1] = '\0';
  }
1184
  return NewStringFromUtf8(CStrVector(buffer), TENURED).ToHandleChecked();
1185 1186 1187
}


1188 1189
Handle<Object> Factory::NewError(const char* maker, const char* message,
                                 Handle<JSArray> args) {
1190
  Handle<String> make_str = InternalizeUtf8String(maker);
1191 1192
  Handle<Object> fun_obj = Object::GetProperty(
      isolate()->js_builtins_object(), make_str).ToHandleChecked();
1193 1194
  // If the builtins haven't been properly configured yet this error
  // constructor may not have been defined.  Bail out.
1195
  if (!fun_obj->IsJSFunction()) {
1196
    return EmergencyNewError(message, args);
1197
  }
1198
  Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
1199 1200
  Handle<Object> message_obj = InternalizeUtf8String(message);
  Handle<Object> argv[] = { message_obj, args };
1201 1202 1203

  // Invoke the JavaScript factory method. If an exception is thrown while
  // running the factory method, use the exception as the result.
1204
  Handle<Object> result;
1205
  MaybeHandle<Object> exception;
1206 1207
  if (!Execution::TryCall(fun,
                          isolate()->js_builtins_object(),
1208
                          arraysize(argv),
1209 1210
                          argv,
                          &exception).ToHandle(&result)) {
1211 1212 1213
    Handle<Object> exception_obj;
    if (exception.ToHandle(&exception_obj)) return exception_obj;
    return undefined_value();
1214
  }
1215 1216 1217 1218
  return result;
}


1219
Handle<Object> Factory::NewError(Handle<String> message) {
1220 1221 1222 1223
  return NewError("$Error", message);
}


1224 1225
Handle<Object> Factory::NewError(const char* constructor,
                                 Handle<String> message) {
1226
  Handle<String> constr = InternalizeUtf8String(constructor);
1227 1228
  Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty(
      isolate()->js_builtins_object(), constr).ToHandleChecked());
1229
  Handle<Object> argv[] = { message };
1230 1231 1232

  // Invoke the JavaScript factory method. If an exception is thrown while
  // running the factory method, use the exception as the result.
1233
  Handle<Object> result;
1234
  MaybeHandle<Object> exception;
1235 1236
  if (!Execution::TryCall(fun,
                          isolate()->js_builtins_object(),
1237
                          arraysize(argv),
1238 1239
                          argv,
                          &exception).ToHandle(&result)) {
1240 1241 1242
    Handle<Object> exception_obj;
    if (exception.ToHandle(&exception_obj)) return exception_obj;
    return undefined_value();
1243
  }
1244 1245 1246 1247
  return result;
}


1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
void Factory::InitializeFunction(Handle<JSFunction> function,
                                 Handle<SharedFunctionInfo> info,
                                 Handle<Context> context) {
  function->initialize_properties();
  function->initialize_elements();
  function->set_shared(*info);
  function->set_code(info->code());
  function->set_context(*context);
  function->set_prototype_or_initial_map(*the_hole_value());
  function->set_literals_or_bindings(*empty_fixed_array());
  function->set_next_function_link(*undefined_value());
}


Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
                                        Handle<SharedFunctionInfo> info,
                                        Handle<Context> context,
                                        PretenureFlag pretenure) {
1266
  AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE;
1267 1268 1269 1270 1271 1272
  Handle<JSFunction> result = New<JSFunction>(map, space);
  InitializeFunction(result, info, context);
  return result;
}


1273 1274 1275
Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
                                        Handle<String> name,
                                        MaybeHandle<Code> code) {
1276
  Handle<Context> context(isolate()->native_context());
1277
  Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name, code);
1278
  DCHECK(is_sloppy(info->language_mode()) &&
1279 1280
         (map.is_identical_to(isolate()->sloppy_function_map()) ||
          map.is_identical_to(
1281 1282 1283
              isolate()->sloppy_function_without_prototype_map()) ||
          map.is_identical_to(
              isolate()->sloppy_function_with_readonly_prototype_map())));
1284
  return NewFunction(map, info, context);
1285 1286 1287
}


1288
Handle<JSFunction> Factory::NewFunction(Handle<String> name) {
1289 1290
  return NewFunction(
      isolate()->sloppy_function_map(), name, MaybeHandle<Code>());
1291 1292 1293
}


1294 1295 1296 1297 1298 1299 1300 1301 1302
Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
                                                        Handle<Code> code) {
  return NewFunction(
      isolate()->sloppy_function_without_prototype_map(), name, code);
}


Handle<JSFunction> Factory::NewFunction(Handle<String> name,
                                        Handle<Code> code,
1303 1304 1305 1306 1307 1308
                                        Handle<Object> prototype,
                                        bool read_only_prototype) {
  Handle<Map> map = read_only_prototype
      ? isolate()->sloppy_function_with_readonly_prototype_map()
      : isolate()->sloppy_function_map();
  Handle<JSFunction> result = NewFunction(map, name, code);
1309 1310 1311 1312 1313
  result->set_prototype_or_initial_map(*prototype);
  return result;
}


1314
Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
1315
                                        Handle<Object> prototype,
1316 1317 1318
                                        InstanceType type, int instance_size,
                                        bool read_only_prototype,
                                        bool install_constructor) {
1319
  // Allocate the function
1320 1321
  Handle<JSFunction> function = NewFunction(
      name, code, prototype, read_only_prototype);
1322

1323 1324 1325
  ElementsKind elements_kind =
      type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;
  Handle<Map> initial_map = NewMap(type, instance_size, elements_kind);
1326 1327 1328 1329 1330 1331 1332
  if (!function->shared()->is_generator()) {
    if (prototype->IsTheHole()) {
      prototype = NewFunctionPrototype(function);
    } else if (install_constructor) {
      JSObject::AddProperty(Handle<JSObject>::cast(prototype),
                            constructor_string(), function, DONT_ENUM);
    }
1333
  }
1334

1335 1336
  JSFunction::SetInitialMap(function, initial_map,
                            Handle<JSReceiver>::cast(prototype));
1337 1338 1339 1340 1341

  return function;
}


1342
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
1343
                                        Handle<Code> code,
1344
                                        InstanceType type,
1345 1346
                                        int instance_size) {
  return NewFunction(name, code, the_hole_value(), type, instance_size);
1347 1348 1349
}


1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
  // Make sure to use globals from the function's context, since the function
  // can be from a different context.
  Handle<Context> native_context(function->context()->native_context());
  Handle<Map> new_map;
  if (function->shared()->is_generator()) {
    // Generator prototypes can share maps since they don't have "constructor"
    // properties.
    new_map = handle(native_context->generator_object_prototype_map());
  } else {
    // Each function prototype gets a fresh map to avoid unwanted sharing of
    // maps between prototypes of different constructors.
    Handle<JSFunction> object_function(native_context->object_function());
1363
    DCHECK(object_function->has_initial_map());
1364
    new_map = handle(object_function->initial_map());
1365 1366
  }

1367
  DCHECK(!new_map->is_prototype_map());
1368 1369 1370
  Handle<JSObject> prototype = NewJSObjectFromMap(new_map);

  if (!function->shared()->is_generator()) {
1371
    JSObject::AddProperty(prototype, constructor_string(), function, DONT_ENUM);
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381
  }

  return prototype;
}


Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
    Handle<SharedFunctionInfo> info,
    Handle<Context> context,
    PretenureFlag pretenure) {
1382 1383
  int map_index =
      Context::FunctionMapIndex(info->language_mode(), info->kind());
1384 1385 1386 1387 1388 1389 1390
  Handle<Map> map(Map::cast(context->native_context()->get(map_index)));
  Handle<JSFunction> result = NewFunction(map, info, context, pretenure);

  if (info->ic_age() != isolate()->heap()->global_ic_age()) {
    info->ResetForNewContext(isolate()->heap()->global_ic_age());
  }

1391 1392 1393 1394
  if (FLAG_always_opt && info->allows_lazy_compilation()) {
    result->MarkForOptimization();
  }

1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
  int index = info->SearchOptimizedCodeMap(context->native_context(),
                                           BailoutId::None());
  if (!info->bound() && index < 0) {
    int number_of_literals = info->num_literals();
    Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
    result->set_literals(*literals);
  }

  if (index > 0) {
    // Caching of optimized code enabled and optimized code found.
    FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
    if (literals != NULL) result->set_literals(literals);
    Code* code = info->GetCodeFromOptimizedCodeMap(index);
1408
    DCHECK(!code->marked_for_deoptimization());
1409 1410 1411 1412 1413 1414 1415
    result->ReplaceCode(code);
  }

  return result;
}


1416
Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
1417 1418 1419 1420
  Handle<FixedArray> array = NewFixedArray(length, TENURED);
  array->set_map_no_write_barrier(*scope_info_map());
  Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(array);
  return scope_info;
1421 1422 1423
}


1424
Handle<JSObject> Factory::NewExternal(void* value) {
1425 1426 1427 1428
  Handle<Foreign> foreign = NewForeign(static_cast<Address>(value));
  Handle<JSObject> external = NewJSObjectFromMap(external_map());
  external->SetInternalField(0, *foreign);
  return external;
1429 1430 1431
}


1432 1433 1434
Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) {
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->AllocateCode(object_size, immovable),
1435 1436 1437 1438
                     Code);
}


1439 1440
Handle<Code> Factory::NewCode(const CodeDesc& desc,
                              Code::Flags flags,
1441
                              Handle<Object> self_ref,
1442
                              bool immovable,
1443
                              bool crankshafted,
1444 1445
                              int prologue_offset,
                              bool is_debug) {
1446 1447 1448 1449 1450 1451 1452 1453
  Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
  Handle<ConstantPoolArray> constant_pool =
      desc.origin->NewConstantPool(isolate());

  // Compute size.
  int body_size = RoundUp(desc.instr_size, kObjectAlignment);
  int obj_size = Code::SizeFor(body_size);

1454
  Handle<Code> code = NewCodeRaw(obj_size, immovable);
1455
  DCHECK(isolate()->code_range() == NULL ||
1456
         !isolate()->code_range()->valid() ||
1457 1458 1459 1460 1461 1462
         isolate()->code_range()->contains(code->address()));

  // The code object has not been fully initialized yet.  We rely on the
  // fact that no allocation will happen from this point on.
  DisallowHeapAllocation no_gc;
  code->set_gc_metadata(Smi::FromInt(0));
ulan's avatar
ulan committed
1463
  code->set_ic_age(isolate()->heap()->global_ic_age());
1464 1465 1466 1467 1468 1469 1470
  code->set_instruction_size(desc.instr_size);
  code->set_relocation_info(*reloc_info);
  code->set_flags(flags);
  code->set_raw_kind_specific_flags1(0);
  code->set_raw_kind_specific_flags2(0);
  code->set_is_crankshafted(crankshafted);
  code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER);
1471
  code->set_raw_type_feedback_info(Smi::FromInt(0));
1472 1473 1474 1475 1476 1477 1478
  code->set_next_code_link(*undefined_value());
  code->set_handler_table(*empty_fixed_array(), SKIP_WRITE_BARRIER);
  code->set_prologue_offset(prologue_offset);
  if (code->kind() == Code::OPTIMIZED_FUNCTION) {
    code->set_marked_for_deoptimization(false);
  }

1479
  if (is_debug) {
1480
    DCHECK(code->kind() == Code::FUNCTION);
1481 1482 1483
    code->set_has_debug_break_slots(true);
  }

1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498
  desc.origin->PopulateConstantPool(*constant_pool);
  code->set_constant_pool(*constant_pool);

  // Allow self references to created code object by patching the handle to
  // point to the newly allocated Code object.
  if (!self_ref.is_null()) *(self_ref.location()) = *code;

  // Migrate generated code.
  // The generated code can contain Object** values (typically from handles)
  // that are dereferenced during the copy to point directly to the actual heap
  // objects. These pointers can include references to the code object itself,
  // through the self_reference parameter.
  code->CopyFrom(desc);

#ifdef VERIFY_HEAP
1499
  if (FLAG_verify_heap) code->ObjectVerify();
1500 1501
#endif
  return code;
1502 1503 1504 1505
}


Handle<Code> Factory::CopyCode(Handle<Code> code) {
1506 1507 1508
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyCode(*code),
                     Code);
1509 1510 1511
}


1512
Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) {
1513 1514 1515
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->CopyCode(*code, reloc_info),
                     Code);
1516 1517 1518
}


1519 1520
Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
                                      PretenureFlag pretenure) {
1521
  JSFunction::EnsureHasInitialMap(constructor);
1522 1523 1524
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject);
1525 1526 1527
}


1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
Handle<JSObject> Factory::NewJSObjectWithMemento(
    Handle<JSFunction> constructor,
    Handle<AllocationSite> site) {
  JSFunction::EnsureHasInitialMap(constructor);
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateJSObject(*constructor, NOT_TENURED, *site),
      JSObject);
}


1539 1540
Handle<JSModule> Factory::NewJSModule(Handle<Context> context,
                                      Handle<ScopeInfo> scope_info) {
1541 1542 1543 1544 1545 1546 1547 1548
  // Allocate a fresh map. Modules do not have a prototype.
  Handle<Map> map = NewMap(JS_MODULE_TYPE, JSModule::kSize);
  // Allocate the object based on the map.
  Handle<JSModule> module =
      Handle<JSModule>::cast(NewJSObjectFromMap(map, TENURED));
  module->set_context(*context);
  module->set_scope_info(*scope_info);
  return module;
1549 1550 1551
}


1552
Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
1553
  DCHECK(constructor->has_initial_map());
1554
  Handle<Map> map(constructor->initial_map());
1555
  DCHECK(map->is_dictionary_map());
1556 1557 1558 1559

  // Make sure no field properties are described in the initial map.
  // This guarantees us that normalizing the properties does not
  // require us to change property values to PropertyCells.
1560
  DCHECK(map->NextFreePropertyIndex() == 0);
1561 1562 1563

  // Make sure we don't have a ton of pre-allocated slots in the
  // global objects. They will be unused once we normalize the object.
1564 1565
  DCHECK(map->unused_property_fields() == 0);
  DCHECK(map->inobject_properties() == 0);
1566 1567 1568 1569 1570 1571 1572 1573

  // Initial size of the backing store to avoid resize of the storage during
  // bootstrapping. The size differs between the JS global object ad the
  // builtins object.
  int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512;

  // Allocate a dictionary object for backing storage.
  int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size;
1574 1575
  Handle<NameDictionary> dictionary =
      NameDictionary::New(isolate(), at_least_space_for);
1576 1577 1578 1579 1580 1581

  // The global object might be created from an object template with accessors.
  // Fill these accessors into the dictionary.
  Handle<DescriptorArray> descs(map->instance_descriptors());
  for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
    PropertyDetails details = descs->GetDetails(i);
1582 1583
    // Only accessors are expected.
    DCHECK_EQ(ACCESSOR_CONSTANT, details.type());
1584 1585
    PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
                      PropertyCellType::kMutable);
1586
    Handle<Name> name(descs->GetKey(i));
1587 1588
    Handle<PropertyCell> cell = NewPropertyCell();
    cell->set_value(descs->GetCallbacksObject(i));
1589 1590
    // |dictionary| already contains enough space for all properties.
    USE(NameDictionary::Add(dictionary, name, cell, d));
1591 1592 1593
  }

  // Allocate the global object and initialize it with the backing store.
1594
  Handle<GlobalObject> global = New<GlobalObject>(map, OLD_SPACE);
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
  isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map);

  // Create a new map for the global object.
  Handle<Map> new_map = Map::CopyDropDescriptors(map);
  new_map->set_dictionary_map(true);

  // Set up the global object as a normalized object.
  global->set_map(*new_map);
  global->set_properties(*dictionary);

  // Make sure result is a global object with properties in dictionary.
1606
  DCHECK(global->IsGlobalObject() && !global->HasFastProperties());
1607 1608 1609
  return global;
}

1610

1611 1612 1613 1614 1615
Handle<JSObject> Factory::NewJSObjectFromMap(
    Handle<Map> map,
    PretenureFlag pretenure,
    bool alloc_props,
    Handle<AllocationSite> allocation_site) {
1616 1617
  CALL_HEAP_FUNCTION(
      isolate(),
1618 1619 1620 1621 1622
      isolate()->heap()->AllocateJSObjectFromMap(
          *map,
          pretenure,
          alloc_props,
          allocation_site.is_null() ? NULL : *allocation_site),
1623
      JSObject);
1624 1625 1626
}


1627 1628
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
                                    PretenureFlag pretenure) {
1629 1630 1631 1632 1633 1634
  Context* native_context = isolate()->context()->native_context();
  JSFunction* array_function = native_context->array_function();
  Map* map = array_function->initial_map();
  Map* transition_map = isolate()->get_initial_js_array_map(elements_kind);
  if (transition_map != NULL) map = transition_map;
  return Handle<JSArray>::cast(NewJSObjectFromMap(handle(map), pretenure));
1635 1636 1637
}


1638 1639 1640
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
                                    int length,
                                    int capacity,
1641
                                    ArrayStorageAllocationMode mode,
1642
                                    PretenureFlag pretenure) {
1643 1644 1645
  Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
  NewJSArrayStorage(array, length, capacity, mode);
  return array;
1646 1647 1648
}


1649
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
1650
                                                ElementsKind elements_kind,
1651
                                                int length,
1652
                                                PretenureFlag pretenure) {
1653
  DCHECK(length <= elements->length());
1654
  Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
1655 1656 1657 1658 1659

  array->set_elements(*elements);
  array->set_length(Smi::FromInt(length));
  JSObject::ValidateElements(array);
  return array;
1660 1661 1662
}


1663
void Factory::NewJSArrayStorage(Handle<JSArray> array,
1664 1665 1666
                                int length,
                                int capacity,
                                ArrayStorageAllocationMode mode) {
1667
  DCHECK(capacity >= length);
1668 1669 1670 1671 1672 1673 1674

  if (capacity == 0) {
    array->set_length(Smi::FromInt(0));
    array->set_elements(*empty_fixed_array());
    return;
  }

1675
  HandleScope inner_scope(isolate());
1676 1677 1678 1679 1680 1681
  Handle<FixedArrayBase> elms;
  ElementsKind elements_kind = array->GetElementsKind();
  if (IsFastDoubleElementsKind(elements_kind)) {
    if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
      elms = NewFixedDoubleArray(capacity);
    } else {
1682
      DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
1683 1684 1685
      elms = NewFixedDoubleArrayWithHoles(capacity);
    }
  } else {
1686
    DCHECK(IsFastSmiOrObjectElementsKind(elements_kind));
1687 1688 1689
    if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
      elms = NewUninitializedFixedArray(capacity);
    } else {
1690
      DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
1691 1692 1693 1694 1695 1696
      elms = NewFixedArrayWithHoles(capacity);
    }
  }

  array->set_elements(*elms);
  array->set_length(Smi::FromInt(length));
1697 1698 1699
}


1700 1701
Handle<JSGeneratorObject> Factory::NewJSGeneratorObject(
    Handle<JSFunction> function) {
1702
  DCHECK(function->shared()->is_generator());
1703 1704
  JSFunction::EnsureHasInitialMap(function);
  Handle<Map> map(function->initial_map());
1705
  DCHECK(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
1706 1707 1708 1709
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateJSObjectFromMap(*map),
      JSGeneratorObject);
1710 1711 1712
}


1713
Handle<JSArrayBuffer> Factory::NewJSArrayBuffer() {
1714
  Handle<JSFunction> array_buffer_fun(
1715
      isolate()->native_context()->array_buffer_fun());
1716 1717 1718 1719
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateJSObject(*array_buffer_fun),
      JSArrayBuffer);
1720 1721 1722
}


1723
Handle<JSDataView> Factory::NewJSDataView() {
1724
  Handle<JSFunction> data_view_fun(
1725
      isolate()->native_context()->data_view_fun());
1726 1727 1728 1729
  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateJSObject(*data_view_fun),
      JSDataView);
1730 1731 1732
}


1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748
Handle<JSMapIterator> Factory::NewJSMapIterator() {
  Handle<Map> map(isolate()->native_context()->map_iterator_map());
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->AllocateJSObjectFromMap(*map),
                     JSMapIterator);
}


Handle<JSSetIterator> Factory::NewJSSetIterator() {
  Handle<Map> map(isolate()->native_context()->set_iterator_map());
  CALL_HEAP_FUNCTION(isolate(),
                     isolate()->heap()->AllocateJSObjectFromMap(*map),
                     JSSetIterator);
}


1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763
namespace {

ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
  switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  case kExternal##Type##Array:                          \
    return EXTERNAL_##TYPE##_ELEMENTS;
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
  }
  UNREACHABLE();
  return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND;
#undef TYPED_ARRAY_CASE
}


1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776
size_t GetExternalArrayElementSize(ExternalArrayType type) {
  switch (type) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  case kExternal##Type##Array:                          \
    return size;
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
  }
  UNREACHABLE();
  return 0;
#undef TYPED_ARRAY_CASE
}


1777
JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
1778
  Context* native_context = isolate->context()->native_context();
1779
  switch (type) {
1780 1781 1782
#define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size)                        \
    case kExternal##Type##Array:                                              \
      return native_context->type##_array_fun();
1783

1784 1785
    TYPED_ARRAYS(TYPED_ARRAY_FUN)
#undef TYPED_ARRAY_FUN
1786

1787 1788
    default:
      UNREACHABLE();
1789
      return NULL;
1790
  }
1791 1792
}

1793 1794 1795 1796 1797 1798 1799 1800 1801 1802

void SetupArrayBufferView(i::Isolate* isolate,
                          i::Handle<i::JSArrayBufferView> obj,
                          i::Handle<i::JSArrayBuffer> buffer,
                          size_t byte_offset, size_t byte_length) {
  DCHECK(byte_offset + byte_length <=
         static_cast<size_t>(buffer->byte_length()->Number()));

  obj->set_buffer(*buffer);

1803 1804 1805 1806 1807 1808 1809 1810
  Heap* heap = isolate->heap();
  if (heap->InNewSpace(*obj)) {
    obj->set_weak_next(heap->new_array_buffer_views_list());
    heap->set_new_array_buffer_views_list(*obj);
  } else {
    obj->set_weak_next(buffer->weak_first_view());
    buffer->set_weak_first_view(*obj);
  }
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821

  i::Handle<i::Object> byte_offset_object =
      isolate->factory()->NewNumberFromSize(byte_offset);
  obj->set_byte_offset(*byte_offset_object);

  i::Handle<i::Object> byte_length_object =
      isolate->factory()->NewNumberFromSize(byte_length);
  obj->set_byte_length(*byte_length_object);
}


1822 1823
}  // namespace

1824 1825 1826

Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
  Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate()));
1827 1828 1829 1830 1831

  CALL_HEAP_FUNCTION(
      isolate(),
      isolate()->heap()->AllocateJSObject(*typed_array_fun_handle),
      JSTypedArray);
1832 1833 1834
}


1835 1836
Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
                                              Handle<JSArrayBuffer> buffer,
1837
                                              size_t byte_offset,
1838
                                              size_t length) {
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
  Handle<JSTypedArray> obj = NewJSTypedArray(type);

  size_t element_size = GetExternalArrayElementSize(type);
  ElementsKind elements_kind = GetExternalArrayElementsKind(type);

  CHECK(byte_offset % element_size == 0);

  CHECK(length <= (std::numeric_limits<size_t>::max() / element_size));
  CHECK(length <= static_cast<size_t>(Smi::kMaxValue));
  size_t byte_length = length * element_size;
  SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);

  Handle<Object> length_object = NewNumberFromSize(length);
  obj->set_length(*length_object);

  Handle<ExternalArray> elements = NewExternalArray(
      static_cast<int>(length), type,
      static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
  Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind);
  JSObject::SetMapAndElements(obj, map, elements);
  return obj;
}


Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
                                          size_t byte_offset,
                                          size_t byte_length) {
  Handle<JSDataView> obj = NewJSDataView();
  SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
  return obj;
1869 1870 1871
}


1872 1873
Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
                                    Handle<Object> prototype) {
1874 1875 1876 1877
  // Allocate map.
  // TODO(rossberg): Once we optimize proxies, think about a scheme to share
  // maps. Will probably depend on the identity of the handler object, too.
  Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
1878
  map->SetPrototype(prototype);
1879 1880 1881 1882 1883 1884 1885

  // Allocate the proxy object.
  Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
  result->InitializeBody(map->instance_size(), Smi::FromInt(0));
  result->set_handler(*handler);
  result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
  return result;
1886 1887 1888
}


1889 1890 1891 1892
Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
                                            Handle<Object> call_trap,
                                            Handle<Object> construct_trap,
                                            Handle<Object> prototype) {
1893 1894 1895 1896
  // Allocate map.
  // TODO(rossberg): Once we optimize proxies, think about a scheme to share
  // maps. Will probably depend on the identity of the handler object, too.
  Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
1897
  map->SetPrototype(prototype);
1898 1899 1900 1901 1902 1903 1904 1905 1906

  // Allocate the proxy object.
  Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
  result->InitializeBody(map->instance_size(), Smi::FromInt(0));
  result->set_handler(*handler);
  result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
  result->set_call_trap(*call_trap);
  result->set_construct_trap(*construct_trap);
  return result;
1907 1908 1909
}


1910 1911 1912
void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type,
                                  int size) {
  DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE);
1913 1914 1915 1916 1917 1918

  // Allocate fresh map.
  // TODO(rossberg): Once we optimize proxies, cache these maps.
  Handle<Map> map = NewMap(type, size);

  // Check that the receiver has at least the size of the fresh object.
1919
  int size_difference = proxy->map()->instance_size() - map->instance_size();
1920
  DCHECK(size_difference >= 0);
1921

1922
  map->SetPrototype(handle(proxy->map()->prototype(), proxy->GetIsolate()));
1923 1924

  // Allocate the backing storage for the properties.
1925
  int prop_size = map->InitialPropertiesLength();
1926 1927 1928 1929 1930
  Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);

  Heap* heap = isolate()->heap();
  MaybeHandle<SharedFunctionInfo> shared;
  if (type == JS_FUNCTION_TYPE) {
1931
    OneByteStringKey key(STATIC_CHAR_VECTOR("<freezing call trap>"),
1932 1933
                         heap->HashSeed());
    Handle<String> name = InternalizeStringWithKey(&key);
1934
    shared = NewSharedFunctionInfo(name, MaybeHandle<Code>());
1935 1936 1937 1938 1939 1940
  }

  // In order to keep heap in consistent state there must be no allocations
  // before object re-initialization is finished and filler object is installed.
  DisallowHeapAllocation no_allocation;

1941 1942
  // Put in filler if the new object is smaller than the old.
  if (size_difference > 0) {
1943
    Address address = proxy->address();
1944
    heap->CreateFillerObjectAt(address + map->instance_size(), size_difference);
1945 1946 1947
    heap->AdjustLiveBytes(address, -size_difference, Heap::FROM_MUTATOR);
  }

1948
  // Reset the map for the object.
1949 1950
  proxy->synchronized_set_map(*map);
  Handle<JSObject> jsobj = Handle<JSObject>::cast(proxy);
1951 1952 1953 1954

  // Reinitialize the object from the constructor map.
  heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);

1955 1956 1957 1958 1959
  // The current native context is used to set up certain bits.
  // TODO(adamk): Using the current context seems wrong, it should be whatever
  // context the JSProxy originated in. But that context isn't stored anywhere.
  Handle<Context> context(isolate()->native_context());

1960 1961 1962
  // Functions require some minimal initialization.
  if (type == JS_FUNCTION_TYPE) {
    map->set_function_with_prototype(true);
1963
    Handle<JSFunction> js_function = Handle<JSFunction>::cast(proxy);
1964
    InitializeFunction(js_function, shared.ToHandleChecked(), context);
1965 1966
  } else {
    // Provide JSObjects with a constructor.
1967
    map->SetConstructor(context->object_function());
1968 1969 1970 1971
  }
}


1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy() {
  // Create an empty shell of a JSGlobalProxy that needs to be reinitialized
  // via ReinitializeJSGlobalProxy later.
  Handle<Map> map = NewMap(JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
  // Maintain invariant expected from any JSGlobalProxy.
  map->set_is_access_check_needed(true);
  CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObjectFromMap(
                                    *map, NOT_TENURED, false),
                     JSGlobalProxy);
}


1984 1985
void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
                                        Handle<JSFunction> constructor) {
1986
  DCHECK(constructor->has_initial_map());
1987 1988
  Handle<Map> map(constructor->initial_map(), isolate());

1989 1990 1991
  // The proxy's hash should be retained across reinitialization.
  Handle<Object> hash(object->hash(), isolate());

1992 1993
  // Check that the already allocated object has the same size and type as
  // objects allocated using the constructor.
1994 1995
  DCHECK(map->instance_size() == object->map()->instance_size());
  DCHECK(map->instance_type() == object->map()->instance_type());
1996 1997

  // Allocate the backing storage for the properties.
1998
  int prop_size = map->InitialPropertiesLength();
1999 2000 2001 2002 2003 2004 2005
  Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED);

  // In order to keep heap in consistent state there must be no allocations
  // before object re-initialization is finished.
  DisallowHeapAllocation no_allocation;

  // Reset the map for the object.
2006
  object->synchronized_set_map(*map);
2007 2008 2009 2010

  Heap* heap = isolate()->heap();
  // Reinitialize the object from the constructor map.
  heap->InitializeJSObjectFromMap(*object, *properties, *map);
2011 2012 2013

  // Restore the saved hash.
  object->set_hash(*hash);
2014 2015 2016
}


2017 2018
void Factory::BecomeJSObject(Handle<JSProxy> proxy) {
  ReinitializeJSProxy(proxy, JS_OBJECT_TYPE, JSObject::kHeaderSize);
2019 2020 2021
}


2022 2023
void Factory::BecomeJSFunction(Handle<JSProxy> proxy) {
  ReinitializeJSProxy(proxy, JS_FUNCTION_TYPE, JSFunction::kSize);
2024 2025 2026
}


2027 2028 2029 2030 2031 2032 2033 2034
template Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
    const ZoneFeedbackVectorSpec* spec);
template Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
    const FeedbackVectorSpec* spec);

template <typename Spec>
Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(const Spec* spec) {
  return TypeFeedbackVector::Allocate<Spec>(isolate(), spec);
2035 2036 2037
}


2038
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
2039 2040
    Handle<String> name, int number_of_literals, FunctionKind kind,
    Handle<Code> code, Handle<ScopeInfo> scope_info,
2041
    Handle<TypeFeedbackVector> feedback_vector) {
2042
  DCHECK(IsValidFunctionKind(kind));
2043
  Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name, code);
2044
  shared->set_scope_info(*scope_info);
2045
  shared->set_feedback_vector(*feedback_vector);
2046
  shared->set_kind(kind);
2047
  shared->set_num_literals(number_of_literals);
2048
  if (IsGeneratorFunction(kind)) {
2049
    shared->set_instance_class_name(isolate()->heap()->Generator_string());
2050
    shared->DisableOptimization(kGenerator);
2051
  }
2052 2053 2054 2055
  return shared;
}


2056 2057 2058 2059 2060 2061 2062
Handle<JSMessageObject> Factory::NewJSMessageObject(
    Handle<String> type,
    Handle<JSArray> arguments,
    int start_position,
    int end_position,
    Handle<Object> script,
    Handle<Object> stack_frames) {
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074
  Handle<Map> map = message_object_map();
  Handle<JSMessageObject> message = New<JSMessageObject>(map, NEW_SPACE);
  message->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER);
  message->initialize_elements();
  message->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
  message->set_type(*type);
  message->set_arguments(*arguments);
  message->set_start_position(start_position);
  message->set_end_position(end_position);
  message->set_script(*script);
  message->set_stack_frames(*stack_frames);
  return message;
2075 2076
}

2077

2078 2079 2080
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
    Handle<String> name,
    MaybeHandle<Code> maybe_code) {
2081
  Handle<Map> map = shared_function_info_map();
2082
  Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, OLD_SPACE);
2083 2084 2085

  // Set pointer fields.
  share->set_name(*name);
2086 2087 2088 2089 2090
  Handle<Code> code;
  if (!maybe_code.ToHandle(&code)) {
    code = handle(isolate()->builtins()->builtin(Builtins::kIllegal));
  }
  share->set_code(*code);
2091 2092 2093 2094 2095 2096 2097 2098 2099 2100
  share->set_optimized_code_map(Smi::FromInt(0));
  share->set_scope_info(ScopeInfo::Empty(isolate()));
  Code* construct_stub =
      isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
  share->set_construct_stub(construct_stub);
  share->set_instance_class_name(*Object_string());
  share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER);
  share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
  share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
  share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
2101
  FeedbackVectorSpec empty_spec(0);
2102
  Handle<TypeFeedbackVector> feedback_vector =
2103
      NewTypeFeedbackVector(&empty_spec);
2104
  share->set_feedback_vector(*feedback_vector, SKIP_WRITE_BARRIER);
2105 2106 2107
#if TRACE_MAPS
  share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
#endif
2108
  share->set_profiler_ticks(0);
2109 2110 2111 2112 2113
  share->set_ast_node_count(0);
  share->set_counters(0);

  // Set integer fields (smi or int, depending on the architecture).
  share->set_length(0);
2114
  share->set_internal_formal_parameter_count(0);
2115 2116 2117 2118 2119 2120 2121 2122 2123 2124
  share->set_expected_nof_properties(0);
  share->set_num_literals(0);
  share->set_start_position_and_type(0);
  share->set_end_position(0);
  share->set_function_token_position(0);
  // All compiler hints default to false or 0.
  share->set_compiler_hints(0);
  share->set_opt_count_and_bailout_reason(0);

  return share;
2125 2126 2127
}


2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169
static inline int NumberCacheHash(Handle<FixedArray> cache,
                                  Handle<Object> number) {
  int mask = (cache->length() >> 1) - 1;
  if (number->IsSmi()) {
    return Handle<Smi>::cast(number)->value() & mask;
  } else {
    DoubleRepresentation rep(number->Number());
    return
        (static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32)) & mask;
  }
}


Handle<Object> Factory::GetNumberStringCache(Handle<Object> number) {
  DisallowHeapAllocation no_gc;
  int hash = NumberCacheHash(number_string_cache(), number);
  Object* key = number_string_cache()->get(hash * 2);
  if (key == *number || (key->IsHeapNumber() && number->IsHeapNumber() &&
                         key->Number() == number->Number())) {
    return Handle<String>(
        String::cast(number_string_cache()->get(hash * 2 + 1)), isolate());
  }
  return undefined_value();
}


void Factory::SetNumberStringCache(Handle<Object> number,
                                   Handle<String> string) {
  int hash = NumberCacheHash(number_string_cache(), number);
  if (number_string_cache()->get(hash * 2) != *undefined_value()) {
    int full_size = isolate()->heap()->FullSizeNumberStringCacheLength();
    if (number_string_cache()->length() != full_size) {
      Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
      isolate()->heap()->set_number_string_cache(*new_cache);
      return;
    }
  }
  number_string_cache()->set(hash * 2, *number);
  number_string_cache()->set(hash * 2 + 1, *string);
}


2170 2171
Handle<String> Factory::NumberToString(Handle<Object> number,
                                       bool check_number_string_cache) {
2172 2173 2174 2175 2176
  isolate()->counters()->number_to_string_runtime()->Increment();
  if (check_number_string_cache) {
    Handle<Object> cached = GetNumberStringCache(number);
    if (!cached->IsUndefined()) return Handle<String>::cast(cached);
  }
2177

2178
  char arr[100];
2179
  Vector<char> buffer(arr, arraysize(arr));
2180 2181 2182 2183 2184 2185 2186 2187
  const char* str;
  if (number->IsSmi()) {
    int num = Handle<Smi>::cast(number)->value();
    str = IntToCString(num, buffer);
  } else {
    double num = Handle<HeapNumber>::cast(number)->value();
    str = DoubleToCString(num, buffer);
  }
2188

2189 2190
  // We tenure the allocated string since it is referenced from the
  // number-string cache which lives in the old space.
2191
  Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED);
2192 2193
  SetNumberStringCache(number, js_string);
  return js_string;
2194 2195 2196
}


2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208
Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
  // Get the original code of the function.
  Handle<Code> code(shared->code());

  // Create a copy of the code before allocating the debug info object to avoid
  // allocation while setting up the debug info object.
  Handle<Code> original_code(*Factory::CopyCode(code));

  // Allocate initial fixed array for active break points before allocating the
  // debug info object to avoid allocation while setting up the debug info
  // object.
  Handle<FixedArray> break_points(
2209
      NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction));
2210 2211 2212 2213 2214

  // Create and set up the debug info object. Debug info contains function, a
  // copy of the original code, the executing code and initial fixed array for
  // active break points.
  Handle<DebugInfo> debug_info =
2215
      Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE));
2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
  debug_info->set_shared(*shared);
  debug_info->set_original_code(*original_code);
  debug_info->set_code(*code);
  debug_info->set_break_points(*break_points);

  // Link debug info to function.
  shared->set_debug_info(*debug_info);

  return debug_info;
}


2228
Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
2229
                                             int length) {
2230 2231
  bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||
                            !callee->is_simple_parameter_list();
2232 2233 2234 2235 2236
  Handle<Map> map = strict_mode_callee ? isolate()->strict_arguments_map()
                                       : isolate()->sloppy_arguments_map();

  AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(),
                                     false);
2237
  DCHECK(!isolate()->has_pending_exception());
2238 2239
  Handle<JSObject> result = NewJSObjectFromMap(map);
  Handle<Smi> value(Smi::FromInt(length), isolate());
2240
  Object::SetProperty(result, length_string(), value, STRICT).Assert();
2241
  if (!strict_mode_callee) {
2242
    Object::SetProperty(result, callee_string(), callee, STRICT).Assert();
2243 2244
  }
  return result;
2245 2246 2247
}


yurys's avatar
yurys committed
2248 2249 2250 2251 2252 2253 2254 2255 2256
Handle<JSWeakMap> Factory::NewJSWeakMap() {
  // TODO(adamk): Currently the map is only created three times per
  // isolate. If it's created more often, the map should be moved into the
  // strong root list.
  Handle<Map> map = NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
  return Handle<JSWeakMap>::cast(NewJSObjectFromMap(map));
}


2257
Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272
                                               int number_of_properties,
                                               bool* is_result_from_cache) {
  const int kMapCacheSize = 128;

  if (number_of_properties > kMapCacheSize) {
    *is_result_from_cache = false;
    return Map::Create(isolate(), number_of_properties);
  }
  *is_result_from_cache = true;
  if (number_of_properties == 0) {
    // Reuse the initial map of the Object function if the literal has no
    // predeclared properties.
    return handle(context->object_function()->initial_map(), isolate());
  }
  int cache_index = number_of_properties - 1;
2273
  if (context->map_cache()->IsUndefined()) {
2274
    // Allocate the new map cache for the native context.
2275
    Handle<FixedArray> new_cache = NewFixedArray(kMapCacheSize, TENURED);
2276 2277
    context->set_map_cache(*new_cache);
  }
2278
  // Check to see whether there is a matching element in the cache.
2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292
  Handle<FixedArray> cache(FixedArray::cast(context->map_cache()));
  {
    Object* result = cache->get(cache_index);
    if (result->IsWeakCell()) {
      WeakCell* cell = WeakCell::cast(result);
      if (!cell->cleared()) {
        return handle(Map::cast(cell->value()), isolate());
      }
    }
  }
  // Create a new map and add it to the cache.
  Handle<Map> map = Map::Create(isolate(), number_of_properties);
  Handle<WeakCell> cell = NewWeakCell(map);
  cache->set(cache_index, *cell);
2293
  return map;
2294 2295 2296
}


2297 2298 2299 2300 2301 2302 2303
void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp,
                                JSRegExp::Type type,
                                Handle<String> source,
                                JSRegExp::Flags flags,
                                Handle<Object> data) {
  Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize);

2304 2305 2306 2307 2308 2309 2310
  store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
  store->set(JSRegExp::kSourceIndex, *source);
  store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value()));
  store->set(JSRegExp::kAtomPatternIndex, *data);
  regexp->set_data(*store);
}

2311

2312 2313 2314 2315 2316 2317
void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
                                    JSRegExp::Type type,
                                    Handle<String> source,
                                    JSRegExp::Flags flags,
                                    int capture_count) {
  Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize);
2318
  Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue);
2319 2320 2321
  store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
  store->set(JSRegExp::kSourceIndex, *source);
  store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value()));
2322
  store->set(JSRegExp::kIrregexpLatin1CodeIndex, uninitialized);
2323
  store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized);
2324
  store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized);
2325
  store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized);
2326 2327 2328 2329 2330 2331 2332
  store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0));
  store->set(JSRegExp::kIrregexpCaptureCountIndex,
             Smi::FromInt(capture_count));
  regexp->set_data(*store);
}


2333
Handle<Object> Factory::GlobalConstantFor(Handle<String> name) {
2334 2335 2336
  if (String::Equals(name, undefined_string())) return undefined_value();
  if (String::Equals(name, nan_string())) return nan_value();
  if (String::Equals(name, infinity_string())) return infinity_value();
2337 2338 2339 2340
  return Handle<Object>::null();
}


2341
Handle<Object> Factory::ToBoolean(bool value) {
2342
  return value ? true_value() : false_value();
2343 2344
}

2345

2346
} }  // namespace v8::internal