| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 uint32_t max_counters_; | 80 uint32_t max_counters_; |
| 81 uint32_t max_name_size_; | 81 uint32_t max_name_size_; |
| 82 uint32_t counters_in_use_; | 82 uint32_t counters_in_use_; |
| 83 Counter counters_[kMaxCounters]; | 83 Counter counters_[kMaxCounters]; |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 | 86 |
| 87 // We statically allocate a set of local counters to be used if we | 87 // We statically allocate a set of local counters to be used if we |
| 88 // don't want to store the stats in a memory-mapped file | 88 // don't want to store the stats in a memory-mapped file |
| 89 static CounterCollection local_counters; | 89 static CounterCollection local_counters; |
| 90 static CounterCollection* counters = &local_counters; | |
| 91 | 90 |
| 92 | 91 |
| 93 typedef std::map<std::string, int*> CounterMap; | 92 typedef std::map<std::string, int*> CounterMap; |
| 94 typedef std::map<std::string, int*>::iterator CounterMapIterator; | 93 typedef std::map<std::string, int*>::iterator CounterMapIterator; |
| 95 static CounterMap counter_table_; | 94 static CounterMap counter_table_; |
| 96 | 95 |
| 97 // Callback receiver when v8 has a counter to track. | |
| 98 static int* counter_callback(const char* name) { | |
| 99 std::string counter = name; | |
| 100 // See if this counter name is already known. | |
| 101 if (counter_table_.find(counter) != counter_table_.end()) | |
| 102 return counter_table_[counter]; | |
| 103 | |
| 104 Counter* ctr = counters->GetNextCounter(); | |
| 105 if (ctr == NULL) return NULL; | |
| 106 int* ptr = ctr->Bind(name); | |
| 107 counter_table_[counter] = ptr; | |
| 108 return ptr; | |
| 109 } | |
| 110 | |
| 111 | 96 |
| 112 class CppByteSink : public i::SnapshotByteSink { | 97 class CppByteSink : public i::SnapshotByteSink { |
| 113 public: | 98 public: |
| 114 explicit CppByteSink(const char* snapshot_file) : bytes_written_(0) { | 99 explicit CppByteSink(const char* snapshot_file) : bytes_written_(0) { |
| 115 fp_ = i::OS::FOpen(snapshot_file, "wb"); | 100 fp_ = i::OS::FOpen(snapshot_file, "wb"); |
| 116 if (fp_ == NULL) { | 101 if (fp_ == NULL) { |
| 117 i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file); | 102 i::PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file); |
| 118 exit(1); | 103 exit(1); |
| 119 } | 104 } |
| 120 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); | 105 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 144 fprintf(fp_, "\n"); | 129 fprintf(fp_, "\n"); |
| 145 } | 130 } |
| 146 } | 131 } |
| 147 | 132 |
| 148 private: | 133 private: |
| 149 FILE* fp_; | 134 FILE* fp_; |
| 150 int bytes_written_; | 135 int bytes_written_; |
| 151 }; | 136 }; |
| 152 | 137 |
| 153 | 138 |
| 154 // Write C++ code that defines Snapshot::snapshot_ to contain the snapshot | |
| 155 // to the file given by filename. Only the first size chars are written. | |
| 156 static int WriteInternalSnapshotToFile(const char* filename, | |
| 157 const v8::internal::byte* bytes, | |
| 158 int size) { | |
| 159 FILE* f = i::OS::FOpen(filename, "wb"); | |
| 160 if (f == NULL) { | |
| 161 i::OS::PrintError("Cannot open file %s for writing.\n", filename); | |
| 162 return 0; | |
| 163 } | |
| 164 fprintf(f, "// Autogenerated snapshot file. Do not edit.\n\n"); | |
| 165 fprintf(f, "#include \"v8.h\"\n"); | |
| 166 fprintf(f, "#include \"platform.h\"\n\n"); | |
| 167 fprintf(f, "#include \"snapshot.h\"\n\n"); | |
| 168 fprintf(f, "namespace v8 {\nnamespace internal {\n\n"); | |
| 169 fprintf(f, "const byte Snapshot::data_[] = {"); | |
| 170 int written = 0; | |
| 171 written += fprintf(f, "0x%x", bytes[0]); | |
| 172 for (int i = 1; i < size; ++i) { | |
| 173 written += fprintf(f, ",0x%x", bytes[i]); | |
| 174 // The following is needed to keep the line length low on Visual C++: | |
| 175 if (i % 512 == 0) fprintf(f, "\n"); | |
| 176 } | |
| 177 fprintf(f, "};\n\n"); | |
| 178 fprintf(f, "int Snapshot::size_ = %d;\n\n", size); | |
| 179 fprintf(f, "} } // namespace v8::internal\n"); | |
| 180 fclose(f); | |
| 181 return written; | |
| 182 } | |
| 183 | |
| 184 | |
| 185 int main2(int argc, char** argv) { | |
| 186 i::Serializer::Enable(); | |
| 187 Persistent<Context> context = v8::Context::New(); | |
| 188 // Make sure all builtin scripts are cached. | |
| 189 { HandleScope scope; | |
| 190 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { | |
| 191 i::Bootstrapper::NativesSourceLookup(i); | |
| 192 } | |
| 193 } | |
| 194 context.Dispose(); | |
| 195 CppByteSink sink(argv[1]); | |
| 196 i::Serializer2 ser(&sink); | |
| 197 // This results in a somewhat smaller snapshot, probably because it gets rid | |
| 198 // of some things that are cached between garbage collections. | |
| 199 i::Heap::CollectAllGarbage(true); | |
| 200 ser.Serialize(); | |
| 201 return 0; | |
| 202 } | |
| 203 | |
| 204 | |
| 205 int main(int argc, char** argv) { | 139 int main(int argc, char** argv) { |
| 206 #ifdef ENABLE_LOGGING_AND_PROFILING | 140 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 207 // By default, log code create information in the snapshot. | 141 // By default, log code create information in the snapshot. |
| 208 i::FLAG_log_code = true; | 142 i::FLAG_log_code = true; |
| 209 #endif | 143 #endif |
| 210 // Print the usage if an error occurs when parsing the command line | 144 // Print the usage if an error occurs when parsing the command line |
| 211 // flags or if the help flag is set. | 145 // flags or if the help flag is set. |
| 212 int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); | 146 int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); |
| 213 if (result > 0 || argc != 2 || i::FLAG_help) { | 147 if (result > 0 || argc != 2 || i::FLAG_help) { |
| 214 ::printf("Usage: %s [flag] ... outfile\n", argv[0]); | 148 ::printf("Usage: %s [flag] ... outfile\n", argv[0]); |
| 215 i::FlagList::PrintHelp(); | 149 i::FlagList::PrintHelp(); |
| 216 return !i::FLAG_help; | 150 return !i::FLAG_help; |
| 217 } | 151 } |
| 218 | |
| 219 if (i::FLAG_new_snapshot) { | |
| 220 return main2(argc, argv); | |
| 221 } | |
| 222 | |
| 223 v8::V8::SetCounterFunction(counter_callback); | |
| 224 v8::HandleScope scope; | |
| 225 | |
| 226 const int kExtensionCount = 1; | |
| 227 const char* extension_list[kExtensionCount] = { "v8/gc" }; | |
| 228 v8::ExtensionConfiguration extensions(kExtensionCount, extension_list); | |
| 229 | |
| 230 i::Serializer::Enable(); | 152 i::Serializer::Enable(); |
| 231 v8::Context::New(&extensions); | 153 Persistent<Context> context = v8::Context::New(); |
| 232 | |
| 233 // Make sure all builtin scripts are cached. | 154 // Make sure all builtin scripts are cached. |
| 234 { HandleScope scope; | 155 { HandleScope scope; |
| 235 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { | 156 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { |
| 236 i::Bootstrapper::NativesSourceLookup(i); | 157 i::Bootstrapper::NativesSourceLookup(i); |
| 237 } | 158 } |
| 238 } | 159 } |
| 239 // Get rid of unreferenced scripts with a global GC. | 160 context.Dispose(); |
| 240 i::Heap::CollectAllGarbage(false); | 161 CppByteSink sink(argv[1]); |
| 241 i::Serializer ser; | 162 i::Serializer ser(&sink); |
| 163 // This results in a somewhat smaller snapshot, probably because it gets rid |
| 164 // of some things that are cached between garbage collections. |
| 165 i::Heap::CollectAllGarbage(true); |
| 242 ser.Serialize(); | 166 ser.Serialize(); |
| 243 v8::internal::byte* bytes; | |
| 244 int len; | |
| 245 ser.Finalize(&bytes, &len); | |
| 246 | |
| 247 WriteInternalSnapshotToFile(argv[1], bytes, len); | |
| 248 | |
| 249 i::DeleteArray(bytes); | |
| 250 | |
| 251 return 0; | 167 return 0; |
| 252 } | 168 } |
| OLD | NEW |