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 |