Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(501)

Side by Side Diff: Source/bindings/core/v8/V8ScriptRunner.cpp

Issue 721373002: Revert "Optionally compress V8 code cache data with snappy." (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 19 matching lines...) Expand all
30 #include "bindings/core/v8/ScriptStreamer.h" 30 #include "bindings/core/v8/ScriptStreamer.h"
31 #include "bindings/core/v8/V8Binding.h" 31 #include "bindings/core/v8/V8Binding.h"
32 #include "bindings/core/v8/V8GCController.h" 32 #include "bindings/core/v8/V8GCController.h"
33 #include "bindings/core/v8/V8RecursionScope.h" 33 #include "bindings/core/v8/V8RecursionScope.h"
34 #include "bindings/core/v8/V8ThrowException.h" 34 #include "bindings/core/v8/V8ThrowException.h"
35 #include "core/dom/ExecutionContext.h" 35 #include "core/dom/ExecutionContext.h"
36 #include "core/fetch/CachedMetadata.h" 36 #include "core/fetch/CachedMetadata.h"
37 #include "core/fetch/ScriptResource.h" 37 #include "core/fetch/ScriptResource.h"
38 #include "platform/ScriptForbiddenScope.h" 38 #include "platform/ScriptForbiddenScope.h"
39 #include "platform/TraceEvent.h" 39 #include "platform/TraceEvent.h"
40 #include "third_party/snappy/src/snappy.h"
41 40
42 namespace blink { 41 namespace blink {
43 42
44 namespace { 43 namespace {
45 44
46 // In order to make sure all pending messages to be processed in 45 // In order to make sure all pending messages to be processed in
47 // v8::Function::Call, we don't call handleMaxRecursionDepthExceeded 46 // v8::Function::Call, we don't call handleMaxRecursionDepthExceeded
48 // directly. Instead, we create a v8::Function of 47 // directly. Instead, we create a v8::Function of
49 // throwStackOverflowException and call it. 48 // throwStackOverflowException and call it.
50 void throwStackOverflowException(const v8::FunctionCallbackInfo<v8::Value>& info ) 49 void throwStackOverflowException(const v8::FunctionCallbackInfo<v8::Value>& info )
51 { 50 {
52 V8ThrowException::throwRangeError(info.GetIsolate(), "Maximum call stack siz e exceeded."); 51 V8ThrowException::throwRangeError(info.GetIsolate(), "Maximum call stack siz e exceeded.");
53 } 52 }
54 53
55 v8::Local<v8::Value> throwStackOverflowExceptionIfNeeded(v8::Isolate* isolate) 54 v8::Local<v8::Value> throwStackOverflowExceptionIfNeeded(v8::Isolate* isolate)
56 { 55 {
57 if (V8PerIsolateData::from(isolate)->isHandlingRecursionLevelError()) { 56 if (V8PerIsolateData::from(isolate)->isHandlingRecursionLevelError()) {
58 // If we are already handling a recursion level error, we should 57 // If we are already handling a recursion level error, we should
59 // not invoke v8::Function::Call. 58 // not invoke v8::Function::Call.
60 return v8::Undefined(isolate); 59 return v8::Undefined(isolate);
61 } 60 }
62 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true); 61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true);
63 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0); 62 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0);
64 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false); 63 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false);
65 return result; 64 return result;
66 } 65 }
67 66
68 void writeToCache(ScriptResource* resource, unsigned cacheTag, Resource::Metadat aCacheType cacheType, const v8::ScriptCompiler::CachedData* cachedData, bool com pressed) 67 v8::Local<v8::Script> compileAndProduceCache(v8::Isolate* isolate, v8::Handle<v8 ::String> code, v8::ScriptOrigin origin, ScriptResource* resource, v8::ScriptCom piler::CompileOptions options, unsigned cacheTag, Resource::MetadataCacheType ca cheType)
69 {
70 const char* data = reinterpret_cast<const char*>(cachedData->data);
71 int length = cachedData->length;
72 std::string compressedOutput;
73 if (compressed) {
74 snappy::Compress(data, length, &compressedOutput);
75 data = compressedOutput.data();
76 length = compressedOutput.length();
77 }
78 resource->clearCachedMetadata();
79 resource->setCachedMetadata(
80 cacheTag,
81 data,
82 length,
83 cacheType);
84 }
85
86 v8::Local<v8::Script> compileAndProduceCache(v8::Isolate* isolate, v8::Handle<v8 ::String> code, v8::ScriptOrigin origin, ScriptResource* resource, v8::ScriptCom piler::CompileOptions options, unsigned cacheTag, Resource::MetadataCacheType ca cheType, bool compressed)
87 { 68 {
88 v8::ScriptCompiler::Source source(code, origin); 69 v8::ScriptCompiler::Source source(code, origin);
89 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options); 70 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options);
90 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData(); 71 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData();
91 if (resource && cachedData) 72 if (resource && cachedData) {
92 writeToCache(resource, cacheTag, cacheType, cachedData, compressed); 73 resource->clearCachedMetadata();
74 resource->setCachedMetadata(
75 cacheTag,
76 reinterpret_cast<const char*>(cachedData->data),
77 cachedData->length,
78 cacheType);
79 }
93 return script; 80 return script;
94 } 81 }
95 82
96 v8::Local<v8::Script> compileAndConsumeCache(v8::Isolate* isolate, v8::Handle<v8 ::String> code, v8::ScriptOrigin origin, ScriptResource* resource, v8::ScriptCom piler::CompileOptions options, unsigned cacheTag, bool compressed) 83 v8::Local<v8::Script> compileAndConsumeCache(v8::Isolate* isolate, v8::Handle<v8 ::String> code, v8::ScriptOrigin origin, ScriptResource* resource, v8::ScriptCom piler::CompileOptions options, unsigned cacheTag)
97 { 84 {
98 // Consume existing cache data: 85 // Consume existing cache data:
99 CachedMetadata* cachedMetadata = resource->cachedMetadata(cacheTag); 86 CachedMetadata* cachedMetadata = resource->cachedMetadata(cacheTag);
100 const char* data = cachedMetadata->data();
101 int length = cachedMetadata->size();
102 std::string uncompressedOutput;
103 if (compressed) {
104 snappy::Uncompress(data, length, &uncompressedOutput);
105 data = uncompressedOutput.data();
106 length = uncompressedOutput.length();
107 }
108 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::CachedD ata( 87 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::CachedD ata(
109 reinterpret_cast<const uint8_t*>(data), 88 reinterpret_cast<const uint8_t*>(cachedMetadata->data()),
110 length, 89 cachedMetadata->size(),
111 v8::ScriptCompiler::CachedData::BufferNotOwned); 90 v8::ScriptCompiler::CachedData::BufferNotOwned);
112 v8::ScriptCompiler::Source source(code, origin, cachedData); 91 v8::ScriptCompiler::Source source(code, origin, cachedData);
113 return v8::ScriptCompiler::Compile(isolate, &source, options); 92 return v8::ScriptCompiler::Compile(isolate, &source, options);
114 } 93 }
115 94
116 } // namespace 95 } // namespace
117 96
118 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) 97 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions)
119 { 98 {
120 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions); 99 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions);
121 } 100 }
122 101
123 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, ScriptStreamer* streamer, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOptions) 102 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, ScriptStreamer* streamer, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOptions)
124 { 103 {
125 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); 104 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8());
126 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); 105 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile");
127 106
128 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at 107 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
129 // 1, whereas v8 starts at 0. 108 // 1, whereas v8 starts at 0.
130 v8::Handle<v8::String> name = v8String(isolate, fileName); 109 v8::Handle<v8::String> name = v8String(isolate, fileName);
131 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt()); 110 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt());
132 v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPositi on.m_column.zeroBasedInt()); 111 v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPositi on.m_column.zeroBasedInt());
133 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate); 112 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate);
134 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); 113 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin);
135 114
136 v8::Local<v8::Script> script; 115 v8::Local<v8::Script> script;
137 unsigned cacheTag = 0; 116 unsigned cacheTag = 0;
138 bool compressed = cacheOptions == V8CacheOptionsCodeCompressed;
139 if (streamer) { 117 if (streamer) {
140 // We don't stream scripts which don't have a Resource. 118 // We don't stream scripts which don't have a Resource.
141 ASSERT(resource); 119 ASSERT(resource);
142 // Failed resources should never get this far. 120 // Failed resources should never get this far.
143 ASSERT(!resource->errorOccurred()); 121 ASSERT(!resource->errorOccurred());
144 ASSERT(streamer->isFinished()); 122 ASSERT(streamer->isFinished());
145 ASSERT(!streamer->streamingSuppressed()); 123 ASSERT(!streamer->streamingSuppressed());
146 script = v8::ScriptCompiler::Compile(isolate, streamer->source(), code, origin); 124 script = v8::ScriptCompiler::Compile(isolate, streamer->source(), code, origin);
147 // Whether to produce the cached data or not is decided when the 125 // Whether to produce the cached data or not is decided when the
148 // streamer is started. Here we only need to get the data out. 126 // streamer is started. Here we only need to get the data out.
149 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source() ->GetCachedData(); 127 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source() ->GetCachedData();
150 if (newCachedData) { 128 if (newCachedData) {
151 // TODO(yangguo,vogelheim): code cache should use Resource::SendToPl atform. 129 resource->clearCachedMetadata();
152 writeToCache(resource, streamer->cachedDataType(), Resource::CacheLo cally, newCachedData, compressed); 130 resource->setCachedMetadata(streamer->cachedDataType(), reinterpret_ cast<const char*>(newCachedData->data), newCachedData->length, Resource::CacheLo cally);
153 } 131 }
154 } else if (!resource || !resource->url().protocolIsInHTTPFamily() || code->L ength() < 1024) { 132 } else if (!resource || !resource->url().protocolIsInHTTPFamily() || code->L ength() < 1024) {
155 v8::ScriptCompiler::Source source(code, origin); 133 v8::ScriptCompiler::Source source(code, origin);
156 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions); 134 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions);
157 } else { 135 } else {
158 Resource::MetadataCacheType cacheType = Resource::CacheLocally;
159 v8::ScriptCompiler::CompileOptions consumeOption = v8::ScriptCompiler::k ConsumeParserCache;
160 v8::ScriptCompiler::CompileOptions produceOption = v8::ScriptCompiler::k ProduceParserCache;
161 switch (cacheOptions) { 136 switch (cacheOptions) {
162 case V8CacheOptionsOff:
163 // Use default.
164 cacheTag = tagForParserCache();
165 break;
166 case V8CacheOptionsParse: 137 case V8CacheOptionsParse:
167 cacheTag = tagForParserCache(); 138 cacheTag = tagForParserCache();
168 cacheType = Resource::SendToPlatform; 139 script = resource->cachedMetadata(cacheTag)
169 consumeOption = v8::ScriptCompiler::kConsumeParserCache; 140 ? compileAndConsumeCache(isolate, code, origin, resource, v8::Sc riptCompiler::kConsumeParserCache, cacheTag)
170 produceOption = v8::ScriptCompiler::kProduceParserCache; 141 : compileAndProduceCache(isolate, code, origin, resource, v8::Sc riptCompiler::kProduceParserCache, cacheTag, Resource::SendToPlatform);
171 break; 142 break;
172 case V8CacheOptionsCodeCompressed:
173 case V8CacheOptionsCode: 143 case V8CacheOptionsCode:
174 cacheTag = tagForCodeCache(); 144 cacheTag = tagForCodeCache();
175 cacheType = Resource::SendToPlatform; 145 script = resource->cachedMetadata(cacheTag)
176 consumeOption = v8::ScriptCompiler::kConsumeCodeCache; 146 ? compileAndConsumeCache(isolate, code, origin, resource, v8::Sc riptCompiler::kConsumeCodeCache, cacheTag)
177 produceOption = v8::ScriptCompiler::kProduceCodeCache; 147 : compileAndProduceCache(isolate, code, origin, resource, v8::Sc riptCompiler::kProduceCodeCache, cacheTag, Resource::SendToPlatform);
148 break;
149 case V8CacheOptionsOff:
150 // Previous behaviour was to always generate an in-memory parser
151 // cache. We emulate this here.
152 // FIXME: Determine whether this should get its own setting, so we
153 // can also have a true 'off'.
154 cacheTag = tagForParserCache();
155 script = resource->cachedMetadata(cacheTag)
156 ? compileAndConsumeCache(isolate, code, origin, resource, v8::Sc riptCompiler::kConsumeParserCache, cacheTag)
157 : compileAndProduceCache(isolate, code, origin, resource, v8::Sc riptCompiler::kProduceParserCache, cacheTag, Resource::CacheLocally);
178 break; 158 break;
179 } 159 }
180 script = resource->cachedMetadata(cacheTag)
181 ? compileAndConsumeCache(isolate, code, origin, resource, consumeOpt ion, cacheTag, compressed)
182 : compileAndProduceCache(isolate, code, origin, resource, produceOpt ion, cacheTag, cacheType, compressed);
183 } 160 }
184 return script; 161 return script;
185 } 162 }
186 163
187 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) 164 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context)
188 { 165 {
189 if (script.IsEmpty()) 166 if (script.IsEmpty())
190 return v8::Local<v8::Value>(); 167 return v8::Local<v8::Value>();
191 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 168 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
192 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); 169 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName())));
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 { 290 {
314 return StringHash::hash(v8::V8::GetVersion()) * 2; 291 return StringHash::hash(v8::V8::GetVersion()) * 2;
315 } 292 }
316 293
317 unsigned V8ScriptRunner::tagForCodeCache() 294 unsigned V8ScriptRunner::tagForCodeCache()
318 { 295 {
319 return StringHash::hash(v8::V8::GetVersion()) * 2 + 1; 296 return StringHash::hash(v8::V8::GetVersion()) * 2 + 1;
320 } 297 }
321 298
322 } // namespace blink 299 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/V8CacheOptions.h ('k') | Source/bindings/core/v8/V8ScriptRunnerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698