~ubuntu-branches/ubuntu/precise/nodejs/precise

« back to all changes in this revision

Viewing changes to deps/v8/src/objects-inl.h

  • Committer: Bazaar Package Importer
  • Author(s): Jérémy Lal
  • Date: 2010-08-20 11:49:04 UTC
  • mfrom: (7.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100820114904-lz22w6fkth7yh179
Tags: 0.2.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
237
237
 
238
238
bool String::IsAsciiRepresentation() {
239
239
  uint32_t type = map()->instance_type();
240
 
  if ((type & kStringRepresentationMask) == kConsStringTag &&
241
 
      ConsString::cast(this)->second()->length() == 0) {
242
 
    return ConsString::cast(this)->first()->IsAsciiRepresentation();
243
 
  }
244
240
  return (type & kStringEncodingMask) == kAsciiStringTag;
245
241
}
246
242
 
247
243
 
248
244
bool String::IsTwoByteRepresentation() {
249
245
  uint32_t type = map()->instance_type();
250
 
  if ((type & kStringRepresentationMask) == kConsStringTag &&
251
 
             ConsString::cast(this)->second()->length() == 0) {
252
 
    return ConsString::cast(this)->first()->IsTwoByteRepresentation();
253
 
  }
254
246
  return (type & kStringEncodingMask) == kTwoByteStringTag;
255
247
}
256
248
 
257
249
 
258
 
bool String::IsExternalTwoByteStringWithAsciiChars() {
259
 
  if (!IsExternalTwoByteString()) return false;
260
 
  const uc16* data = ExternalTwoByteString::cast(this)->resource()->data();
261
 
  for (int i = 0, len = length(); i < len; i++) {
262
 
    if (data[i] > kMaxAsciiCharCode) return false;
263
 
  }
264
 
  return true;
 
250
bool String::HasOnlyAsciiChars() {
 
251
  uint32_t type = map()->instance_type();
 
252
  return (type & kStringEncodingMask) == kAsciiStringTag ||
 
253
         (type & kAsciiDataHintMask) == kAsciiDataHintTag;
265
254
}
266
255
 
267
256
 
759
748
    ASSERT(mode == SKIP_WRITE_BARRIER); \
760
749
    ASSERT(Heap::InNewSpace(object) || \
761
750
           !Heap::InNewSpace(READ_FIELD(object, offset)) || \
762
 
           Page::IsRSetSet(object->address(), offset)); \
 
751
           Page::FromAddress(object->address())->           \
 
752
               IsRegionDirty(object->address() + offset));  \
763
753
  }
764
754
 
765
755
#define READ_DOUBLE_FIELD(p, offset) \
1045
1035
void HeapObject::VerifyObjectField(int offset) {
1046
1036
  VerifyPointer(READ_FIELD(this, offset));
1047
1037
}
 
1038
 
 
1039
void HeapObject::VerifySmiField(int offset) {
 
1040
  ASSERT(READ_FIELD(this, offset)->IsSmi());
 
1041
}
1048
1042
#endif
1049
1043
 
1050
1044
 
1064
1058
 
1065
1059
 
1066
1060
void HeapObject::set_map_word(MapWord map_word) {
1067
 
  // WRITE_FIELD does not update the remembered set, but there is no need
 
1061
  // WRITE_FIELD does not invoke write barrier, but there is no need
1068
1062
  // here.
1069
1063
  WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1070
1064
}
1162
1156
ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
1163
1157
 
1164
1158
 
1165
 
Array* JSObject::elements() {
 
1159
HeapObject* JSObject::elements() {
1166
1160
  Object* array = READ_FIELD(this, kElementsOffset);
1167
1161
  // In the assert below Dictionary is covered under FixedArray.
1168
1162
  ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1169
1163
         array->IsExternalArray());
1170
 
  return reinterpret_cast<Array*>(array);
 
1164
  return reinterpret_cast<HeapObject*>(array);
1171
1165
}
1172
1166
 
1173
1167
 
1174
 
void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
 
1168
void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
 
1169
  ASSERT(map()->has_fast_elements() ==
 
1170
         (value->map() == Heap::fixed_array_map()));
1175
1171
  // In the assert below Dictionary is covered under FixedArray.
1176
1172
  ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1177
1173
         value->IsExternalArray());
1187
1183
 
1188
1184
 
1189
1185
void JSObject::initialize_elements() {
 
1186
  ASSERT(map()->has_fast_elements());
1190
1187
  ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1191
1188
  WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1192
1189
}
1193
1190
 
1194
1191
 
 
1192
Object* JSObject::ResetElements() {
 
1193
  Object* obj = map()->GetFastElementsMap();
 
1194
  if (obj->IsFailure()) return obj;
 
1195
  set_map(Map::cast(obj));
 
1196
  initialize_elements();
 
1197
  return this;
 
1198
}
 
1199
 
 
1200
 
1195
1201
ACCESSORS(Oddball, to_string, String, kToStringOffset)
1196
1202
ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1197
1203
 
1329
1335
}
1330
1336
 
1331
1337
 
1332
 
void Struct::InitializeBody(int object_size) {
1333
 
  Object* value = Heap::undefined_value();
1334
 
  for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
1335
 
    WRITE_FIELD(this, offset, value);
1336
 
  }
1337
 
}
1338
 
 
1339
 
 
1340
1338
bool JSObject::HasFastProperties() {
1341
1339
  return !properties()->IsDictionary();
1342
1340
}
1343
1341
 
1344
1342
 
1345
 
bool Array::IndexFromObject(Object* object, uint32_t* index) {
1346
 
  if (object->IsSmi()) {
1347
 
    int value = Smi::cast(object)->value();
 
1343
int JSObject::MaxFastProperties() {
 
1344
  // Allow extra fast properties if the object has more than
 
1345
  // kMaxFastProperties in-object properties. When this is the case,
 
1346
  // it is very unlikely that the object is being used as a dictionary
 
1347
  // and there is a good chance that allowing more map transitions
 
1348
  // will be worth it.
 
1349
  return Max(map()->inobject_properties(), kMaxFastProperties);
 
1350
}
 
1351
 
 
1352
 
 
1353
void Struct::InitializeBody(int object_size) {
 
1354
  Object* value = Heap::undefined_value();
 
1355
  for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
 
1356
    WRITE_FIELD(this, offset, value);
 
1357
  }
 
1358
}
 
1359
 
 
1360
 
 
1361
bool Object::ToArrayIndex(uint32_t* index) {
 
1362
  if (IsSmi()) {
 
1363
    int value = Smi::cast(this)->value();
1348
1364
    if (value < 0) return false;
1349
1365
    *index = value;
1350
1366
    return true;
1351
1367
  }
1352
 
  if (object->IsHeapNumber()) {
1353
 
    double value = HeapNumber::cast(object)->value();
 
1368
  if (IsHeapNumber()) {
 
1369
    double value = HeapNumber::cast(this)->value();
1354
1370
    uint32_t uint_value = static_cast<uint32_t>(value);
1355
1371
    if (value == static_cast<double>(uint_value)) {
1356
1372
      *index = uint_value;
1477
1493
}
1478
1494
 
1479
1495
 
 
1496
int DescriptorArray::SearchWithCache(String* name) {
 
1497
  int number = DescriptorLookupCache::Lookup(this, name);
 
1498
  if (number == DescriptorLookupCache::kAbsent) {
 
1499
    number = Search(name);
 
1500
    DescriptorLookupCache::Update(this, name, number);
 
1501
  }
 
1502
  return number;
 
1503
}
 
1504
 
 
1505
 
1480
1506
String* DescriptorArray::GetKey(int descriptor_number) {
1481
1507
  ASSERT(descriptor_number < number_of_descriptors());
1482
1508
  return String::cast(get(ToKeyIndex(descriptor_number)));
1665
1691
}
1666
1692
 
1667
1693
 
1668
 
INT_ACCESSORS(Array, length, kLengthOffset)
 
1694
SMI_ACCESSORS(FixedArray, length, kLengthOffset)
 
1695
SMI_ACCESSORS(ByteArray, length, kLengthOffset)
 
1696
 
 
1697
INT_ACCESSORS(PixelArray, length, kLengthOffset)
 
1698
INT_ACCESSORS(ExternalArray, length, kLengthOffset)
1669
1699
 
1670
1700
 
1671
1701
SMI_ACCESSORS(String, length, kLengthOffset)
1678
1708
 
1679
1709
void String::set_hash_field(uint32_t value) {
1680
1710
  WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
 
1711
#if V8_HOST_ARCH_64_BIT
 
1712
  WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
 
1713
#endif
1681
1714
}
1682
1715
 
1683
1716
 
2038
2071
}
2039
2072
 
2040
2073
 
 
2074
INT_ACCESSORS(Map, visitor_id, kScavengerCallbackOffset)
 
2075
 
2041
2076
int Map::instance_size() {
2042
2077
  return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2043
2078
}
2061
2096
      (kStringTag | kConsStringTag) ||
2062
2097
      instance_type == JS_ARRAY_TYPE) return map->instance_size();
2063
2098
  if (instance_type == FIXED_ARRAY_TYPE) {
2064
 
    return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
 
2099
    return FixedArray::BodyDescriptor::SizeOf(map, this);
2065
2100
  }
2066
2101
  if (instance_type == BYTE_ARRAY_TYPE) {
2067
2102
    return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2176
2211
}
2177
2212
 
2178
2213
 
 
2214
void Map::set_is_extensible(bool value) {
 
2215
  if (value) {
 
2216
    set_bit_field2(bit_field2() | (1 << kIsExtensible));
 
2217
  } else {
 
2218
    set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
 
2219
  }
 
2220
}
 
2221
 
 
2222
bool Map::is_extensible() {
 
2223
  return ((1 << kIsExtensible) & bit_field2()) != 0;
 
2224
}
 
2225
 
 
2226
 
 
2227
 
2179
2228
Code::Flags Code::flags() {
2180
2229
  return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2181
2230
}
2184
2233
void Code::set_flags(Code::Flags flags) {
2185
2234
  STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
2186
2235
  // Make sure that all call stubs have an arguments count.
2187
 
  ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
 
2236
  ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
 
2237
          ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
2188
2238
         ExtractArgumentsCountFromFlags(flags) >= 0);
2189
2239
  WRITE_INT_FIELD(this, kFlagsOffset, flags);
2190
2240
}
2220
2270
 
2221
2271
 
2222
2272
int Code::arguments_count() {
2223
 
  ASSERT(is_call_stub() || kind() == STUB);
 
2273
  ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
2224
2274
  return ExtractArgumentsCountFromFlags(flags());
2225
2275
}
2226
2276
 
2249
2299
                               InLoopFlag in_loop,
2250
2300
                               InlineCacheState ic_state,
2251
2301
                               PropertyType type,
2252
 
                               int argc) {
 
2302
                               int argc,
 
2303
                               InlineCacheHolderFlag holder) {
2253
2304
  // Compute the bit mask.
2254
2305
  int bits = kind << kFlagsKindShift;
2255
2306
  if (in_loop) bits |= kFlagsICInLoopMask;
2256
2307
  bits |= ic_state << kFlagsICStateShift;
2257
2308
  bits |= type << kFlagsTypeShift;
2258
2309
  bits |= argc << kFlagsArgumentsCountShift;
 
2310
  if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
2259
2311
  // Cast to flags and validate result before returning it.
2260
2312
  Flags result = static_cast<Flags>(bits);
2261
2313
  ASSERT(ExtractKindFromFlags(result) == kind);
2269
2321
 
2270
2322
Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2271
2323
                                          PropertyType type,
 
2324
                                          InlineCacheHolderFlag holder,
2272
2325
                                          InLoopFlag in_loop,
2273
2326
                                          int argc) {
2274
 
  return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
 
2327
  return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc, holder);
2275
2328
}
2276
2329
 
2277
2330
 
2304
2357
}
2305
2358
 
2306
2359
 
 
2360
InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
 
2361
  int bits = (flags & kFlagsCacheInPrototypeMapMask);
 
2362
  return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
 
2363
}
 
2364
 
 
2365
 
2307
2366
Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2308
2367
  int bits = flags & ~kFlagsTypeMask;
2309
2368
  return static_cast<Flags>(bits);
2333
2392
}
2334
2393
 
2335
2394
 
 
2395
Object* Map::GetFastElementsMap() {
 
2396
  if (has_fast_elements()) return this;
 
2397
  Object* obj = CopyDropTransitions();
 
2398
  if (obj->IsFailure()) return obj;
 
2399
  Map* new_map = Map::cast(obj);
 
2400
  new_map->set_has_fast_elements(true);
 
2401
  return new_map;
 
2402
}
 
2403
 
 
2404
 
 
2405
Object* Map::GetSlowElementsMap() {
 
2406
  if (!has_fast_elements()) return this;
 
2407
  Object* obj = CopyDropTransitions();
 
2408
  if (obj->IsFailure()) return obj;
 
2409
  Map* new_map = Map::cast(obj);
 
2410
  new_map->set_has_fast_elements(false);
 
2411
  return new_map;
 
2412
}
 
2413
 
 
2414
 
2336
2415
ACCESSORS(Map, instance_descriptors, DescriptorArray,
2337
2416
          kInstanceDescriptorsOffset)
2338
2417
ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
2455
2534
               compiler_hints,
2456
2535
               try_full_codegen,
2457
2536
               kTryFullCodegen)
2458
 
 
2459
 
INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2460
 
INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2461
 
              kFormalParameterCountOffset)
2462
 
INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2463
 
              kExpectedNofPropertiesOffset)
2464
 
INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
2465
 
INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2466
 
              kStartPositionAndTypeOffset)
2467
 
INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2468
 
INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2469
 
              kFunctionTokenPositionOffset)
2470
 
INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2471
 
              kCompilerHintsOffset)
2472
 
INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2473
 
              kThisPropertyAssignmentsCountOffset)
2474
 
 
 
2537
BOOL_ACCESSORS(SharedFunctionInfo,
 
2538
               compiler_hints,
 
2539
               allows_lazy_compilation,
 
2540
               kAllowLazyCompilation)
 
2541
 
 
2542
#if V8_HOST_ARCH_32_BIT
 
2543
SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
 
2544
SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
 
2545
              kFormalParameterCountOffset)
 
2546
SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
 
2547
              kExpectedNofPropertiesOffset)
 
2548
SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
 
2549
SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
 
2550
              kStartPositionAndTypeOffset)
 
2551
SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
 
2552
SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
 
2553
              kFunctionTokenPositionOffset)
 
2554
SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
 
2555
              kCompilerHintsOffset)
 
2556
SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
 
2557
              kThisPropertyAssignmentsCountOffset)
 
2558
#else
 
2559
 
 
2560
#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
 
2561
  int holder::name() {                                            \
 
2562
    int value = READ_INT_FIELD(this, offset);                     \
 
2563
    ASSERT(kHeapObjectTag == 1);                                  \
 
2564
    ASSERT((value & kHeapObjectTag) == 0);                        \
 
2565
    return value >> 1;                                            \
 
2566
  }                                                               \
 
2567
  void holder::set_##name(int value) {                            \
 
2568
    ASSERT(kHeapObjectTag == 1);                                  \
 
2569
    ASSERT((value & 0xC0000000) == 0xC0000000 ||                  \
 
2570
           (value & 0xC0000000) == 0x000000000);                  \
 
2571
    WRITE_INT_FIELD(this,                                         \
 
2572
                    offset,                                       \
 
2573
                    (value << 1) & ~kHeapObjectTag);              \
 
2574
  }
 
2575
 
 
2576
#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
 
2577
  INT_ACCESSORS(holder, name, offset)
 
2578
 
 
2579
 
 
2580
 
 
2581
PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
 
2582
PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
 
2583
              kFormalParameterCountOffset)
 
2584
 
 
2585
PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
 
2586
              kExpectedNofPropertiesOffset)
 
2587
PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
 
2588
 
 
2589
PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
 
2590
              kStartPositionAndTypeOffset)
 
2591
PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
 
2592
 
 
2593
PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
 
2594
              kFunctionTokenPositionOffset)
 
2595
PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
 
2596
              kCompilerHintsOffset)
 
2597
 
 
2598
PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
 
2599
              kThisPropertyAssignmentsCountOffset)
 
2600
#endif
2475
2601
 
2476
2602
ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2477
2603
ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2518
2644
}
2519
2645
 
2520
2646
 
 
2647
SerializedScopeInfo* SharedFunctionInfo::scope_info() {
 
2648
  return reinterpret_cast<SerializedScopeInfo*>(
 
2649
      READ_FIELD(this, kScopeInfoOffset));
 
2650
}
 
2651
 
 
2652
 
 
2653
void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
 
2654
                                        WriteBarrierMode mode) {
 
2655
  WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
 
2656
  CONDITIONAL_WRITE_BARRIER(this, kScopeInfoOffset, mode);
 
2657
}
 
2658
 
 
2659
 
2521
2660
bool SharedFunctionInfo::is_compiled() {
2522
 
  // TODO(1242782): Create a code kind for uncompiled code.
2523
 
  return code()->kind() != Code::STUB;
 
2661
  return code() != Builtins::builtin(Builtins::LazyCompile);
2524
2662
}
2525
2663
 
2526
2664
 
2552
2690
 
2553
2691
 
2554
2692
Code* JSFunction::code() {
2555
 
  return shared()->code();
 
2693
  return Code::cast(READ_FIELD(this, kCodeOffset));
2556
2694
}
2557
2695
 
2558
2696
 
2559
2697
void JSFunction::set_code(Code* value) {
2560
 
  shared()->set_code(value);
 
2698
  // Skip the write barrier because code is never in new space.
 
2699
  ASSERT(!Heap::InNewSpace(value));
 
2700
  WRITE_FIELD(this, kCodeOffset, value);
2561
2701
}
2562
2702
 
2563
2703
 
2629
2769
 
2630
2770
 
2631
2771
bool JSFunction::is_compiled() {
2632
 
  return shared()->is_compiled();
 
2772
  return code() != Builtins::builtin(Builtins::LazyCompile);
2633
2773
}
2634
2774
 
2635
2775
 
2676
2816
}
2677
2817
 
2678
2818
 
2679
 
void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2680
 
  visitor->VisitExternalReference(
2681
 
      reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2682
 
}
2683
 
 
2684
 
 
2685
2819
ACCESSORS(JSValue, value, Object, kValueOffset)
2686
2820
 
2687
2821
 
2693
2827
 
2694
2828
 
2695
2829
INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2696
 
INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2697
 
INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
 
2830
ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
2698
2831
 
2699
2832
 
2700
2833
byte* Code::instruction_start()  {
2702
2835
}
2703
2836
 
2704
2837
 
 
2838
byte* Code::instruction_end()  {
 
2839
  return instruction_start() + instruction_size();
 
2840
}
 
2841
 
 
2842
 
2705
2843
int Code::body_size() {
2706
 
  return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
 
2844
  return RoundUp(instruction_size(), kObjectAlignment);
 
2845
}
 
2846
 
 
2847
 
 
2848
ByteArray* Code::unchecked_relocation_info() {
 
2849
  return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
2707
2850
}
2708
2851
 
2709
2852
 
2710
2853
byte* Code::relocation_start() {
2711
 
  return FIELD_ADDR(this, kHeaderSize + instruction_size());
 
2854
  return unchecked_relocation_info()->GetDataStartAddress();
 
2855
}
 
2856
 
 
2857
 
 
2858
int Code::relocation_size() {
 
2859
  return unchecked_relocation_info()->length();
2712
2860
}
2713
2861
 
2714
2862
 
2723
2871
}
2724
2872
 
2725
2873
 
2726
 
byte* Code::sinfo_start() {
2727
 
  return FIELD_ADDR(this, kHeaderSize + body_size());
2728
 
}
2729
 
 
2730
 
 
2731
2874
ACCESSORS(JSArray, length, Object, kLengthOffset)
2732
2875
 
2733
2876
 
2785
2928
 
2786
2929
 
2787
2930
JSObject::ElementsKind JSObject::GetElementsKind() {
2788
 
  Array* array = elements();
 
2931
  HeapObject* array = elements();
2789
2932
  if (array->IsFixedArray()) {
2790
2933
    // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2791
2934
    if (array->map() == Heap::fixed_array_map()) {
 
2935
      ASSERT(map()->has_fast_elements());
2792
2936
      return FAST_ELEMENTS;
2793
2937
    }
2794
2938
    ASSERT(array->IsDictionary());
 
2939
    ASSERT(!map()->has_fast_elements());
2795
2940
    return DICTIONARY_ELEMENTS;
2796
2941
  }
 
2942
  ASSERT(!map()->has_fast_elements());
2797
2943
  if (array->IsExternalArray()) {
2798
2944
    switch (array->map()->instance_type()) {
2799
2945
      case EXTERNAL_BYTE_ARRAY_TYPE:
2908
3054
}
2909
3055
 
2910
3056
 
 
3057
bool String::IsHashFieldComputed(uint32_t field) {
 
3058
  return (field & kHashNotComputedMask) == 0;
 
3059
}
 
3060
 
 
3061
 
2911
3062
bool String::HasHashCode() {
2912
 
  return (hash_field() & kHashComputedMask) != 0;
 
3063
  return IsHashFieldComputed(hash_field());
2913
3064
}
2914
3065
 
2915
3066
 
2916
3067
uint32_t String::Hash() {
2917
3068
  // Fast case: has hash code already been computed?
2918
3069
  uint32_t field = hash_field();
2919
 
  if (field & kHashComputedMask) return field >> kHashShift;
 
3070
  if (IsHashFieldComputed(field)) return field >> kHashShift;
2920
3071
  // Slow case: compute hash code and set it.
2921
3072
  return ComputeAndSetHash();
2922
3073
}
2989
3140
 
2990
3141
bool String::AsArrayIndex(uint32_t* index) {
2991
3142
  uint32_t field = hash_field();
2992
 
  if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
 
3143
  if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
 
3144
    return false;
 
3145
  }
2993
3146
  return SlowAsArrayIndex(index);
2994
3147
}
2995
3148
 
3113
3266
 
3114
3267
void JSArray::EnsureSize(int required_size) {
3115
3268
  ASSERT(HasFastElements());
3116
 
  Array* elts = elements();
 
3269
  FixedArray* elts = FixedArray::cast(elements());
3117
3270
  const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3118
3271
  if (elts->length() < required_size) {
3119
3272
    // Doubling in size would be overkill, but leave some slack to avoid
3146
3299
}
3147
3300
 
3148
3301
 
 
3302
int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
 
3303
  return map->instance_size();
 
3304
}
 
3305
 
 
3306
 
 
3307
void Proxy::ProxyIterateBody(ObjectVisitor* v) {
 
3308
  v->VisitExternalReference(
 
3309
      reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
 
3310
}
 
3311
 
 
3312
 
 
3313
template<typename StaticVisitor>
 
3314
void Proxy::ProxyIterateBody() {
 
3315
  StaticVisitor::VisitExternalReference(
 
3316
      reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
 
3317
}
 
3318
 
 
3319
 
 
3320
void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
 
3321
  typedef v8::String::ExternalAsciiStringResource Resource;
 
3322
  v->VisitExternalAsciiString(
 
3323
      reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
 
3324
}
 
3325
 
 
3326
 
 
3327
template<typename StaticVisitor>
 
3328
void ExternalAsciiString::ExternalAsciiStringIterateBody() {
 
3329
  typedef v8::String::ExternalAsciiStringResource Resource;
 
3330
  StaticVisitor::VisitExternalAsciiString(
 
3331
      reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
 
3332
}
 
3333
 
 
3334
 
 
3335
void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
 
3336
  typedef v8::String::ExternalStringResource Resource;
 
3337
  v->VisitExternalTwoByteString(
 
3338
      reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
 
3339
}
 
3340
 
 
3341
 
 
3342
template<typename StaticVisitor>
 
3343
void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
 
3344
  typedef v8::String::ExternalStringResource Resource;
 
3345
  StaticVisitor::VisitExternalTwoByteString(
 
3346
      reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
 
3347
}
 
3348
 
 
3349
#define SLOT_ADDR(obj, offset) \
 
3350
  reinterpret_cast<Object**>((obj)->address() + offset)
 
3351
 
 
3352
template<int start_offset, int end_offset, int size>
 
3353
void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
 
3354
    HeapObject* obj,
 
3355
    ObjectVisitor* v) {
 
3356
    v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
 
3357
}
 
3358
 
 
3359
 
 
3360
template<int start_offset>
 
3361
void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
 
3362
                                                       int object_size,
 
3363
                                                       ObjectVisitor* v) {
 
3364
  v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
 
3365
}
 
3366
 
 
3367
#undef SLOT_ADDR
 
3368
 
 
3369
 
3149
3370
#undef CAST_ACCESSOR
3150
3371
#undef INT_ACCESSORS
3151
3372
#undef SMI_ACCESSORS