| Index: src/parser.cc
 | 
| diff --git a/src/parser.cc b/src/parser.cc
 | 
| index a048e91e79d08dc24befb848cde3bbac9fa28684..30c2c6344067ba8821a4d1ee32969cfa5e8c8236 100644
 | 
| --- a/src/parser.cc
 | 
| +++ b/src/parser.cc
 | 
| @@ -224,7 +224,33 @@ Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
 | 
| +ScriptData* ScriptData::New(const char* data, int length) {
 | 
| +  // The length is obviously invalid.
 | 
| +  if (length % sizeof(unsigned) != 0) {
 | 
| +    return new ScriptData();
 | 
| +  }
 | 
| +
 | 
| +  int deserialized_data_length = length / sizeof(unsigned);
 | 
| +  unsigned* deserialized_data;
 | 
| +  ScriptData* script_data = new ScriptData();
 | 
| +  script_data->owns_store_ =
 | 
| +      reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0;
 | 
| +  if (script_data->owns_store_) {
 | 
| +    // Copy the data to align it.
 | 
| +    deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
 | 
| +    i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
 | 
| +                 data, static_cast<size_t>(length));
 | 
| +  } else {
 | 
| +    // If aligned, don't create a copy of the data.
 | 
| +    deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data));
 | 
| +  }
 | 
| +  script_data->store_ =
 | 
| +      Vector<unsigned>(deserialized_data, deserialized_data_length);
 | 
| +  return script_data;
 | 
| +}
 | 
| +
 | 
| +
 | 
| +FunctionEntry ScriptData::GetFunctionEntry(int start) {
 | 
|    // The current pre-data entry must be a FunctionEntry with the given
 | 
|    // start position.
 | 
|    if ((function_index_ + FunctionEntry::kSize <= store_.length())
 | 
| @@ -238,12 +264,12 @@ FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -int ScriptDataImpl::GetSymbolIdentifier() {
 | 
| +int ScriptData::GetSymbolIdentifier() {
 | 
|    return ReadNumber(&symbol_data_);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool ScriptDataImpl::SanityCheck() {
 | 
| +bool ScriptData::SanityCheck() {
 | 
|    // Check that the header data is valid and doesn't specify
 | 
|    // point to positions outside the store.
 | 
|    if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
 | 
| @@ -292,7 +318,7 @@ bool ScriptDataImpl::SanityCheck() {
 | 
|  
 | 
|  
 | 
|  
 | 
| -const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
 | 
| +const char* ScriptData::ReadString(unsigned* start, int* chars) {
 | 
|    int length = start[0];
 | 
|    char* result = NewArray<char>(length + 1);
 | 
|    for (int i = 0; i < length; i++) {
 | 
| @@ -304,25 +330,25 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Scanner::Location ScriptDataImpl::MessageLocation() const {
 | 
| +Scanner::Location ScriptData::MessageLocation() const {
 | 
|    int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
 | 
|    int end_pos = Read(PreparseDataConstants::kMessageEndPos);
 | 
|    return Scanner::Location(beg_pos, end_pos);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool ScriptDataImpl::IsReferenceError() const {
 | 
| +bool ScriptData::IsReferenceError() const {
 | 
|    return Read(PreparseDataConstants::kIsReferenceErrorPos);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -const char* ScriptDataImpl::BuildMessage() const {
 | 
| +const char* ScriptData::BuildMessage() const {
 | 
|    unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
 | 
|    return ReadString(start, NULL);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Vector<const char*> ScriptDataImpl::BuildArgs() const {
 | 
| +Vector<const char*> ScriptData::BuildArgs() const {
 | 
|    int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
 | 
|    const char** array = NewArray<const char*>(arg_count);
 | 
|    // Position after text found by skipping past length field and
 | 
| @@ -338,12 +364,12 @@ Vector<const char*> ScriptDataImpl::BuildArgs() const {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -unsigned ScriptDataImpl::Read(int position) const {
 | 
| +unsigned ScriptData::Read(int position) const {
 | 
|    return store_[PreparseDataConstants::kHeaderSize + position];
 | 
|  }
 | 
|  
 | 
|  
 | 
| -unsigned* ScriptDataImpl::ReadAddress(int position) const {
 | 
| +unsigned* ScriptData::ReadAddress(int position) const {
 | 
|    return &store_[PreparseDataConstants::kHeaderSize + position];
 | 
|  }
 | 
|  
 | 
| @@ -890,7 +916,7 @@ FunctionLiteral* Parser::ParseProgram() {
 | 
|    }
 | 
|    if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
 | 
|      Vector<unsigned> store = recorder.ExtractData();
 | 
| -    *cached_data_ = new ScriptDataImpl(store);
 | 
| +    *cached_data_ = new ScriptData(store);
 | 
|      log_ = NULL;
 | 
|    }
 | 
|    return result;
 | 
| @@ -4537,27 +4563,27 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
 | 
|  // ----------------------------------------------------------------------------
 | 
|  // The Parser interface.
 | 
|  
 | 
| -ScriptDataImpl::~ScriptDataImpl() {
 | 
| +ScriptData::~ScriptData() {
 | 
|    if (owns_store_) store_.Dispose();
 | 
|  }
 | 
|  
 | 
|  
 | 
| -int ScriptDataImpl::Length() {
 | 
| +int ScriptData::Length() {
 | 
|    return store_.length() * sizeof(unsigned);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -const char* ScriptDataImpl::Data() {
 | 
| +const char* ScriptData::Data() {
 | 
|    return reinterpret_cast<const char*>(store_.start());
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool ScriptDataImpl::HasError() {
 | 
| +bool ScriptData::HasError() {
 | 
|    return has_error();
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void ScriptDataImpl::Initialize() {
 | 
| +void ScriptData::Initialize() {
 | 
|    // Prepares state for use.
 | 
|    if (store_.length() >= PreparseDataConstants::kHeaderSize) {
 | 
|      function_index_ = PreparseDataConstants::kHeaderSize;
 | 
| @@ -4574,7 +4600,7 @@ void ScriptDataImpl::Initialize() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -int ScriptDataImpl::ReadNumber(byte** source) {
 | 
| +int ScriptData::ReadNumber(byte** source) {
 | 
|    // Reads a number from symbol_data_ in base 128. The most significant
 | 
|    // bit marks that there are more digits.
 | 
|    // If the first byte is 0x80 (kNumberTerminator), it would normally
 | 
| @@ -4601,33 +4627,6 @@ int ScriptDataImpl::ReadNumber(byte** source) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Create a Scanner for the preparser to use as input, and preparse the source.
 | 
| -ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate,
 | 
| -                                       Utf16CharacterStream* source) {
 | 
| -  CompleteParserRecorder recorder;
 | 
| -  HistogramTimerScope timer(isolate->counters()->pre_parse());
 | 
| -  Scanner scanner(isolate->unicode_cache());
 | 
| -  intptr_t stack_limit = isolate->stack_guard()->real_climit();
 | 
| -  PreParser preparser(&scanner, &recorder, stack_limit);
 | 
| -  preparser.set_allow_lazy(true);
 | 
| -  preparser.set_allow_generators(FLAG_harmony_generators);
 | 
| -  preparser.set_allow_for_of(FLAG_harmony_iteration);
 | 
| -  preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
 | 
| -  preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
 | 
| -  scanner.Initialize(source);
 | 
| -  PreParser::PreParseResult result = preparser.PreParseProgram();
 | 
| -  if (result == PreParser::kPreParseStackOverflow) {
 | 
| -    isolate->StackOverflow();
 | 
| -    return NULL;
 | 
| -  }
 | 
| -
 | 
| -  // Extract the accumulated data from the recorder as a single
 | 
| -  // contiguous vector that we are responsible for disposing.
 | 
| -  Vector<unsigned> store = recorder.ExtractData();
 | 
| -  return new ScriptDataImpl(store);
 | 
| -}
 | 
| -
 | 
| -
 | 
|  bool RegExpParser::ParseRegExp(FlatStringReader* input,
 | 
|                                 bool multiline,
 | 
|                                 RegExpCompileData* result,
 | 
| @@ -4665,7 +4664,7 @@ bool Parser::Parse() {
 | 
|      SetCachedData(info()->cached_data(), info()->cached_data_mode());
 | 
|      if (info()->cached_data_mode() == CONSUME_CACHED_DATA &&
 | 
|          (*info()->cached_data())->has_error()) {
 | 
| -      ScriptDataImpl* cached_data = *(info()->cached_data());
 | 
| +      ScriptData* cached_data = *(info()->cached_data());
 | 
|        Scanner::Location loc = cached_data->MessageLocation();
 | 
|        const char* message = cached_data->BuildMessage();
 | 
|        Vector<const char*> args = cached_data->BuildArgs();
 | 
| 
 |