~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to deps/v8/src/serialize.h

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2006-2009 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
170
170
    return data_[position_++];
171
171
  }
172
172
 
 
173
  int32_t GetUnalignedInt() {
 
174
#if defined(V8_HOST_CAN_READ_UNALIGNED) &&  __BYTE_ORDER == __LITTLE_ENDIAN
 
175
    int32_t answer;
 
176
    ASSERT(position_ + sizeof(answer) <= length_ + 0u);
 
177
    answer = *reinterpret_cast<const int32_t*>(data_ + position_);
 
178
#else
 
179
    int32_t answer = data_[position_];
 
180
    answer |= data_[position_ + 1] << 8;
 
181
    answer |= data_[position_ + 2] << 16;
 
182
    answer |= data_[position_ + 3] << 24;
 
183
#endif
 
184
    return answer;
 
185
  }
 
186
 
 
187
  void Advance(int by) { position_ += by; }
 
188
 
173
189
  inline void CopyRaw(byte* to, int number_of_bytes);
174
190
 
175
191
  inline int GetInt();
176
192
 
177
 
  bool AtEOF() {
178
 
    return position_ == length_;
179
 
  }
 
193
  bool AtEOF();
180
194
 
181
195
  int position() { return position_; }
182
196
 
187
201
};
188
202
 
189
203
 
190
 
// It is very common to have a reference to objects at certain offsets in the
191
 
// heap.  These offsets have been determined experimentally.  We code
192
 
// references to such objects in a single byte that encodes the way the pointer
193
 
// is written (only plain pointers allowed), the space number and the offset.
194
 
// This only works for objects in the first page of a space.  Don't use this for
195
 
// things in newspace since it bypasses the write barrier.
196
 
 
197
 
static const int k64 = (sizeof(uintptr_t) - 4) / 4;
198
 
 
199
 
#define COMMON_REFERENCE_PATTERNS(f)                               \
200
 
  f(kNumberOfSpaces, 2, (11 - k64))                                \
201
 
  f((kNumberOfSpaces + 1), 2, 0)                                   \
202
 
  f((kNumberOfSpaces + 2), 2, (142 - 16 * k64))                    \
203
 
  f((kNumberOfSpaces + 3), 2, (74 - 15 * k64))                     \
204
 
  f((kNumberOfSpaces + 4), 2, 5)                                   \
205
 
  f((kNumberOfSpaces + 5), 1, 135)                                 \
206
 
  f((kNumberOfSpaces + 6), 2, (228 - 39 * k64))
207
 
 
208
 
#define COMMON_RAW_LENGTHS(f)        \
209
 
  f(1, 1)  \
210
 
  f(2, 2)  \
211
 
  f(3, 3)  \
212
 
  f(4, 4)  \
213
 
  f(5, 5)  \
214
 
  f(6, 6)  \
215
 
  f(7, 7)  \
216
 
  f(8, 8)  \
217
 
  f(9, 12)  \
218
 
  f(10, 16) \
219
 
  f(11, 20) \
220
 
  f(12, 24) \
221
 
  f(13, 28) \
222
 
  f(14, 32) \
223
 
  f(15, 36)
224
 
 
225
204
// The Serializer/Deserializer class is a common superclass for Serializer and
226
205
// Deserializer which is used to store common constants and methods used by
227
206
// both.
228
207
class SerializerDeserializer: public ObjectVisitor {
229
208
 public:
230
209
  static void Iterate(ObjectVisitor* visitor);
231
 
  static void SetSnapshotCacheSize(int size);
 
210
 
 
211
  static int nop() { return kNop; }
232
212
 
233
213
 protected:
234
214
  // Where the pointed-to object can be found:
235
215
  enum Where {
236
216
    kNewObject = 0,                 // Object is next in snapshot.
237
 
    // 1-8                             One per space.
 
217
    // 1-6                             One per space.
238
218
    kRootArray = 0x9,               // Object is found in root array.
239
219
    kPartialSnapshotCache = 0xa,    // Object is in the cache.
240
220
    kExternalReference = 0xb,       // Pointer to an external reference.
241
 
    // 0xc-0xf                         Free.
242
 
    kBackref = 0x10,                 // Object is described relative to end.
243
 
    // 0x11-0x18                       One per space.
244
 
    // 0x19-0x1f                       Common backref offsets.
245
 
    kFromStart = 0x20,              // Object is described relative to start.
246
 
    // 0x21-0x28                       One per space.
247
 
    // 0x29-0x2f                       Free.
248
 
    // 0x30-0x3f                       Used by misc tags below.
 
221
    kSkip = 0xc,                    // Skip n bytes.
 
222
    kNop = 0xd,                     // Does nothing, used to pad.
 
223
    // 0xe-0xf                         Free.
 
224
    kBackref = 0x10,                // Object is described relative to end.
 
225
    // 0x11-0x16                       One per space.
 
226
    kBackrefWithSkip = 0x18,        // Object is described relative to end.
 
227
    // 0x19-0x1e                       One per space.
 
228
    // 0x20-0x3f                       Used by misc. tags below.
249
229
    kPointedToMask = 0x3f
250
230
  };
251
231
 
257
237
    kHowToCodeMask = 0x40
258
238
  };
259
239
 
 
240
  // For kRootArrayConstants
 
241
  enum WithSkip {
 
242
    kNoSkipDistance = 0,
 
243
    kHasSkipDistance = 0x40,
 
244
    kWithSkipMask = 0x40
 
245
  };
 
246
 
260
247
  // Where to point within the object.
261
248
  enum WhereToPoint {
262
249
    kStartOfObject = 0,
263
 
    kFirstInstruction = 0x80,
 
250
    kInnerPointer = 0x80,  // First insn in code object or payload of cell.
264
251
    kWhereToPointMask = 0x80
265
252
  };
266
253
 
267
254
  // Misc.
268
 
  // Raw data to be copied from the snapshot.
269
 
  static const int kRawData = 0x30;
270
 
  // Some common raw lengths: 0x31-0x3f
 
255
  // Raw data to be copied from the snapshot.  This byte code does not advance
 
256
  // the current pointer, which is used for code objects, where we write the
 
257
  // entire code in one memcpy, then fix up stuff with kSkip and other byte
 
258
  // codes that overwrite data.
 
259
  static const int kRawData = 0x20;
 
260
  // Some common raw lengths: 0x21-0x3f.  These autoadvance the current pointer.
271
261
  // A tag emitted at strategic points in the snapshot to delineate sections.
272
262
  // If the deserializer does not find these at the expected moments then it
273
263
  // is an indication that the snapshot and the VM do not fit together.
277
267
  // Used for the source code of the natives, which is in the executable, but
278
268
  // is referred to from external strings in the snapshot.
279
269
  static const int kNativesStringResource = 0x71;
280
 
  static const int kNewPage = 0x72;
281
 
  // 0x73-0x7f                            Free.
282
 
  // 0xb0-0xbf                            Free.
283
 
  // 0xf0-0xff                            Free.
284
 
 
285
 
 
286
 
  static const int kLargeData = LAST_SPACE;
287
 
  static const int kLargeCode = kLargeData + 1;
288
 
  static const int kLargeFixedArray = kLargeCode + 1;
289
 
  static const int kNumberOfSpaces = kLargeFixedArray + 1;
 
270
  static const int kRepeat = 0x72;
 
271
  static const int kConstantRepeat = 0x73;
 
272
  // 0x73-0x7f            Repeat last word (subtract 0x72 to get the count).
 
273
  static const int kMaxRepeats = 0x7f - 0x72;
 
274
  static int CodeForRepeats(int repeats) {
 
275
    ASSERT(repeats >= 1 && repeats <= kMaxRepeats);
 
276
    return 0x72 + repeats;
 
277
  }
 
278
  static int RepeatsForCode(int byte_code) {
 
279
    ASSERT(byte_code >= kConstantRepeat && byte_code <= 0x7f);
 
280
    return byte_code - 0x72;
 
281
  }
 
282
  static const int kRootArrayConstants = 0xa0;
 
283
  // 0xa0-0xbf            Things from the first 32 elements of the root array.
 
284
  static const int kRootArrayNumberOfConstantEncodings = 0x20;
 
285
  static int RootArrayConstantFromByteCode(int byte_code) {
 
286
    return byte_code & 0x1f;
 
287
  }
 
288
 
 
289
  static const int kNumberOfSpaces = LO_SPACE;
290
290
  static const int kAnyOldSpace = -1;
291
291
 
292
292
  // A bitmask for getting the space out of an instruction.
293
 
  static const int kSpaceMask = 15;
294
 
 
295
 
  static inline bool SpaceIsLarge(int space) { return space >= kLargeData; }
296
 
  static inline bool SpaceIsPaged(int space) {
297
 
    return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE;
298
 
  }
 
293
  static const int kSpaceMask = 7;
299
294
};
300
295
 
301
296
 
302
297
int SnapshotByteSource::GetInt() {
303
 
  // A little unwind to catch the really small ints.
304
 
  int snapshot_byte = Get();
305
 
  if ((snapshot_byte & 0x80) == 0) {
306
 
    return snapshot_byte;
307
 
  }
308
 
  int accumulator = (snapshot_byte & 0x7f) << 7;
309
 
  while (true) {
310
 
    snapshot_byte = Get();
311
 
    if ((snapshot_byte & 0x80) == 0) {
312
 
      return accumulator | snapshot_byte;
313
 
    }
314
 
    accumulator = (accumulator | (snapshot_byte & 0x7f)) << 7;
315
 
  }
316
 
  UNREACHABLE();
317
 
  return accumulator;
 
298
  // This way of variable-length encoding integers does not suffer from branch
 
299
  // mispredictions.
 
300
  uint32_t answer = GetUnalignedInt();
 
301
  int bytes = answer & 3;
 
302
  Advance(bytes);
 
303
  uint32_t mask = 0xffffffffu;
 
304
  mask >>= 32 - (bytes << 3);
 
305
  answer &= mask;
 
306
  answer >>= 2;
 
307
  return answer;
318
308
}
319
309
 
320
310
 
338
328
  // Deserialize a single object and the objects reachable from it.
339
329
  void DeserializePartial(Object** root);
340
330
 
341
 
#ifdef DEBUG
342
 
  virtual void Synchronize(const char* tag);
343
 
#endif
 
331
  void set_reservation(int space_number, int reservation) {
 
332
    ASSERT(space_number >= 0);
 
333
    ASSERT(space_number <= LAST_SPACE);
 
334
    reservations_[space_number] = reservation;
 
335
  }
344
336
 
345
337
 private:
346
338
  virtual void VisitPointers(Object** start, Object** end);
353
345
    UNREACHABLE();
354
346
  }
355
347
 
356
 
  void ReadChunk(Object** start, Object** end, int space, Address address);
357
 
  HeapObject* GetAddressFromStart(int space);
358
 
  inline HeapObject* GetAddressFromEnd(int space);
359
 
  Address Allocate(int space_number, Space* space, int size);
360
 
  void ReadObject(int space_number, Space* space, Object** write_back);
 
348
  // Fills in some heap data in an area from start to end (non-inclusive).  The
 
349
  // space id is used for the write barrier.  The object_address is the address
 
350
  // of the object we are writing into, or NULL if we are not writing into an
 
351
  // object, i.e. if we are writing a series of tagged values that are not on
 
352
  // the heap.
 
353
  void ReadChunk(
 
354
      Object** start, Object** end, int space, Address object_address);
 
355
  void ReadObject(int space_number, Object** write_back);
 
356
 
 
357
  // This routine both allocates a new object, and also keeps
 
358
  // track of where objects have been allocated so that we can
 
359
  // fix back references when deserializing.
 
360
  Address Allocate(int space_index, int size) {
 
361
    Address address = high_water_[space_index];
 
362
    high_water_[space_index] = address + size;
 
363
    return address;
 
364
  }
 
365
 
 
366
  // This returns the address of an object that has been described in the
 
367
  // snapshot as being offset bytes back in a particular space.
 
368
  HeapObject* GetAddressFromEnd(int space) {
 
369
    int offset = source_->GetInt();
 
370
    offset <<= kObjectAlignmentBits;
 
371
    return HeapObject::FromAddress(high_water_[space] - offset);
 
372
  }
 
373
 
361
374
 
362
375
  // Cached current isolate.
363
376
  Isolate* isolate_;
364
377
 
365
 
  // Keep track of the pages in the paged spaces.
366
 
  // (In large object space we are keeping track of individual objects
367
 
  // rather than pages.)  In new space we just need the address of the
368
 
  // first object and the others will flow from that.
369
 
  List<Address> pages_[SerializerDeserializer::kNumberOfSpaces];
370
 
 
371
378
  SnapshotByteSource* source_;
372
379
  // This is the address of the next object that will be allocated in each
373
380
  // space.  It is used to calculate the addresses of back-references.
374
381
  Address high_water_[LAST_SPACE + 1];
375
 
  // This is the address of the most recent object that was allocated.  It
376
 
  // is used to set the location of the new page when we encounter a
377
 
  // START_NEW_PAGE_SERIALIZATION tag.
378
 
  Address last_object_address_;
 
382
 
 
383
  int reservations_[LAST_SPACE + 1];
 
384
  static const intptr_t kUninitializedReservation = -1;
379
385
 
380
386
  ExternalReferenceDecoder* external_reference_decoder_;
381
387
 
457
463
  // You can call this after serialization to find out how much space was used
458
464
  // in each space.
459
465
  int CurrentAllocationAddress(int space) {
460
 
    if (SpaceIsLarge(space)) return large_object_total_;
 
466
    ASSERT(space < kNumberOfSpaces);
461
467
    return fullness_[space];
462
468
  }
463
469
 
474
480
  static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
475
481
  static bool enabled() { return serialization_enabled_; }
476
482
  SerializationAddressMapper* address_mapper() { return &address_mapper_; }
477
 
#ifdef DEBUG
478
 
  virtual void Synchronize(const char* tag);
479
 
#endif
 
483
  void PutRoot(int index,
 
484
               HeapObject* object,
 
485
               HowToCode how,
 
486
               WhereToPoint where,
 
487
               int skip);
480
488
 
481
489
 protected:
482
490
  static const int kInvalidRootIndex = -1;
483
 
  virtual int RootIndex(HeapObject* heap_object) = 0;
 
491
 
 
492
  int RootIndex(HeapObject* heap_object, HowToCode from);
484
493
  virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0;
 
494
  intptr_t root_index_wave_front() { return root_index_wave_front_; }
 
495
  void set_root_index_wave_front(intptr_t value) {
 
496
    ASSERT(value >= root_index_wave_front_);
 
497
    root_index_wave_front_ = value;
 
498
  }
485
499
 
486
500
  class ObjectSerializer : public ObjectVisitor {
487
501
   public:
494
508
        object_(HeapObject::cast(o)),
495
509
        sink_(sink),
496
510
        reference_representation_(how_to_code + where_to_point),
497
 
        bytes_processed_so_far_(0) { }
 
511
        bytes_processed_so_far_(0),
 
512
        code_object_(o->IsCode()),
 
513
        code_has_been_output_(false) { }
498
514
    void Serialize();
499
515
    void VisitPointers(Object** start, Object** end);
 
516
    void VisitEmbeddedPointer(RelocInfo* target);
500
517
    void VisitExternalReferences(Address* start, Address* end);
 
518
    void VisitExternalReference(RelocInfo* rinfo);
501
519
    void VisitCodeTarget(RelocInfo* target);
502
520
    void VisitCodeEntry(Address entry_address);
503
521
    void VisitGlobalPropertyCell(RelocInfo* rinfo);
512
530
    }
513
531
 
514
532
   private:
515
 
    void OutputRawData(Address up_to);
 
533
    enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn };
 
534
    // This function outputs or skips the raw data between the last pointer and
 
535
    // up to the current position.  It optionally can just return the number of
 
536
    // bytes to skip instead of performing a skip instruction, in case the skip
 
537
    // can be merged into the next instruction.
 
538
    int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn);
516
539
 
517
540
    Serializer* serializer_;
518
541
    HeapObject* object_;
519
542
    SnapshotByteSink* sink_;
520
543
    int reference_representation_;
521
544
    int bytes_processed_so_far_;
 
545
    bool code_object_;
 
546
    bool code_has_been_output_;
522
547
  };
523
548
 
524
549
  virtual void SerializeObject(Object* o,
525
550
                               HowToCode how_to_code,
526
 
                               WhereToPoint where_to_point) = 0;
 
551
                               WhereToPoint where_to_point,
 
552
                               int skip) = 0;
527
553
  void SerializeReferenceToPreviousObject(
528
554
      int space,
529
555
      int address,
530
556
      HowToCode how_to_code,
531
 
      WhereToPoint where_to_point);
 
557
      WhereToPoint where_to_point,
 
558
      int skip);
532
559
  void InitializeAllocators();
533
 
  // This will return the space for an object.  If the object is in large
534
 
  // object space it may return kLargeCode or kLargeFixedArray in order
535
 
  // to indicate to the deserializer what kind of large object allocation
536
 
  // to make.
 
560
  // This will return the space for an object.
537
561
  static int SpaceOfObject(HeapObject* object);
538
 
  // This just returns the space of the object.  It will return LO_SPACE
539
 
  // for all large objects since you can't check the type of the object
540
 
  // once the map has been used for the serialization address.
541
 
  static int SpaceOfAlreadySerializedObject(HeapObject* object);
542
 
  int Allocate(int space, int size, bool* new_page_started);
 
562
  int Allocate(int space, int size);
543
563
  int EncodeExternalReference(Address addr) {
544
564
    return external_reference_encoder_->Encode(addr);
545
565
  }
546
566
 
 
567
  int SpaceAreaSize(int space);
 
568
 
 
569
  Isolate* isolate_;
547
570
  // Keep track of the fullness of each space in order to generate
548
 
  // relative addresses for back references.  Large objects are
549
 
  // just numbered sequentially since relative addresses make no
550
 
  // sense in large object space.
 
571
  // relative addresses for back references.
551
572
  int fullness_[LAST_SPACE + 1];
552
573
  SnapshotByteSink* sink_;
553
574
  int current_root_index_;
555
576
  static bool serialization_enabled_;
556
577
  // Did we already make use of the fact that serialization was not enabled?
557
578
  static bool too_late_to_enable_now_;
558
 
  int large_object_total_;
559
579
  SerializationAddressMapper address_mapper_;
 
580
  intptr_t root_index_wave_front_;
 
581
  void Pad();
560
582
 
561
583
  friend class ObjectSerializer;
562
584
  friend class Deserializer;
563
585
 
 
586
 private:
564
587
  DISALLOW_COPY_AND_ASSIGN(Serializer);
565
588
};
566
589
 
571
594
                    SnapshotByteSink* sink)
572
595
    : Serializer(sink),
573
596
      startup_serializer_(startup_snapshot_serializer) {
 
597
    set_root_index_wave_front(Heap::kStrongRootListLength);
574
598
  }
575
599
 
576
600
  // Serialize the objects reachable from a single object pointer.
577
601
  virtual void Serialize(Object** o);
578
602
  virtual void SerializeObject(Object* o,
579
603
                               HowToCode how_to_code,
580
 
                               WhereToPoint where_to_point);
 
604
                               WhereToPoint where_to_point,
 
605
                               int skip);
581
606
 
582
607
 protected:
583
 
  virtual int RootIndex(HeapObject* o);
584
608
  virtual int PartialSnapshotCacheIndex(HeapObject* o);
585
609
  virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) {
586
610
    // Scripts should be referred only through shared function infos.  We can't
590
614
    ASSERT(!o->IsScript());
591
615
    return o->IsString() || o->IsSharedFunctionInfo() ||
592
616
           o->IsHeapNumber() || o->IsCode() ||
593
 
           o->IsSerializedScopeInfo() ||
 
617
           o->IsScopeInfo() ||
594
618
           o->map() == HEAP->fixed_cow_array_map();
595
619
  }
596
620
 
605
629
  explicit StartupSerializer(SnapshotByteSink* sink) : Serializer(sink) {
606
630
    // Clear the cache of objects used by the partial snapshot.  After the
607
631
    // strong roots have been serialized we can create a partial snapshot
608
 
    // which will repopulate the cache with objects neede by that partial
 
632
    // which will repopulate the cache with objects needed by that partial
609
633
    // snapshot.
610
634
    Isolate::Current()->set_serialize_partial_snapshot_cache_length(0);
611
635
  }
612
636
  // Serialize the current state of the heap.  The order is:
613
637
  // 1) Strong references.
614
638
  // 2) Partial snapshot cache.
615
 
  // 3) Weak references (eg the symbol table).
 
639
  // 3) Weak references (e.g. the symbol table).
616
640
  virtual void SerializeStrongReferences();
617
641
  virtual void SerializeObject(Object* o,
618
642
                               HowToCode how_to_code,
619
 
                               WhereToPoint where_to_point);
 
643
                               WhereToPoint where_to_point,
 
644
                               int skip);
620
645
  void SerializeWeakReferences();
621
646
  void Serialize() {
622
647
    SerializeStrongReferences();
623
648
    SerializeWeakReferences();
 
649
    Pad();
624
650
  }
625
651
 
626
652
 private:
627
 
  virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; }
628
653
  virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) {
629
654
    return false;
630
655
  }