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

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

Issue 720783002: Optionally compress V8 code cache data with snappy. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fix for the default case 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
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 20 matching lines...) Expand all
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 40
41 #include <snappy.h>
42
41 namespace blink { 43 namespace blink {
42 44
43 namespace { 45 namespace {
44 46
45 // In order to make sure all pending messages to be processed in 47 // In order to make sure all pending messages to be processed in
46 // v8::Function::Call, we don't call handleMaxRecursionDepthExceeded 48 // v8::Function::Call, we don't call handleMaxRecursionDepthExceeded
47 // directly. Instead, we create a v8::Function of 49 // directly. Instead, we create a v8::Function of
48 // throwStackOverflowException and call it. 50 // throwStackOverflowException and call it.
49 void throwStackOverflowException(const v8::FunctionCallbackInfo<v8::Value>& info ) 51 void throwStackOverflowException(const v8::FunctionCallbackInfo<v8::Value>& info )
50 { 52 {
51 V8ThrowException::throwRangeError(info.GetIsolate(), "Maximum call stack siz e exceeded."); 53 V8ThrowException::throwRangeError(info.GetIsolate(), "Maximum call stack siz e exceeded.");
52 } 54 }
53 55
54 v8::Local<v8::Value> throwStackOverflowExceptionIfNeeded(v8::Isolate* isolate) 56 v8::Local<v8::Value> throwStackOverflowExceptionIfNeeded(v8::Isolate* isolate)
55 { 57 {
56 if (V8PerIsolateData::from(isolate)->isHandlingRecursionLevelError()) { 58 if (V8PerIsolateData::from(isolate)->isHandlingRecursionLevelError()) {
57 // If we are already handling a recursion level error, we should 59 // If we are already handling a recursion level error, we should
58 // not invoke v8::Function::Call. 60 // not invoke v8::Function::Call.
59 return v8::Undefined(isolate); 61 return v8::Undefined(isolate);
60 } 62 }
61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true); 63 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true);
62 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0); 64 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0);
63 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false); 65 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false);
64 return result; 66 return result;
65 } 67 }
66 68
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 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)
68 { 70 {
69 v8::ScriptCompiler::Source source(code, origin); 71 v8::ScriptCompiler::Source source(code, origin);
70 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options); 72 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options);
71 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData(); 73 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData();
72 if (resource && cachedData) { 74 if (resource && cachedData) {
75 const char* data = reinterpret_cast<const char*>(cachedData->data);
76 int length = cachedData->length;
77 std::string compressedOutput;
78 if (compressed) {
79 snappy::Compress(data, length, &compressedOutput);
80 data = compressedOutput.data();
81 length = compressedOutput.length();
82 }
73 resource->clearCachedMetadata(); 83 resource->clearCachedMetadata();
74 resource->setCachedMetadata( 84 resource->setCachedMetadata(
75 cacheTag, 85 cacheTag,
76 reinterpret_cast<const char*>(cachedData->data), 86 data,
77 cachedData->length, 87 length,
78 cacheType); 88 cacheType);
79 } 89 }
80 return script; 90 return script;
81 } 91 }
82 92
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) 93 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)
84 { 94 {
85 // Consume existing cache data: 95 // Consume existing cache data:
86 CachedMetadata* cachedMetadata = resource->cachedMetadata(cacheTag); 96 CachedMetadata* cachedMetadata = resource->cachedMetadata(cacheTag);
97 const char* data = cachedMetadata->data();
98 int length = cachedMetadata->size();
99 std::string uncompressedOutput;
100 if (compressed) {
101 snappy::Uncompress(data, length, &uncompressedOutput);
102 data = uncompressedOutput.data();
103 length = uncompressedOutput.length();
104 }
87 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::CachedD ata( 105 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::CachedD ata(
88 reinterpret_cast<const uint8_t*>(cachedMetadata->data()), 106 reinterpret_cast<const uint8_t*>(data),
89 cachedMetadata->size(), 107 length,
90 v8::ScriptCompiler::CachedData::BufferNotOwned); 108 v8::ScriptCompiler::CachedData::BufferNotOwned);
91 v8::ScriptCompiler::Source source(code, origin, cachedData); 109 v8::ScriptCompiler::Source source(code, origin, cachedData);
92 return v8::ScriptCompiler::Compile(isolate, &source, options); 110 return v8::ScriptCompiler::Compile(isolate, &source, options);
93 } 111 }
94 112
95 } // namespace 113 } // namespace
96 114
97 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) 115 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions)
98 { 116 {
99 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions); 117 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions);
(...skipping 26 matching lines...) Expand all
126 // streamer is started. Here we only need to get the data out. 144 // streamer is started. Here we only need to get the data out.
127 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source() ->GetCachedData(); 145 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source() ->GetCachedData();
128 if (newCachedData) { 146 if (newCachedData) {
129 resource->clearCachedMetadata(); 147 resource->clearCachedMetadata();
130 resource->setCachedMetadata(streamer->cachedDataType(), reinterpret_ cast<const char*>(newCachedData->data), newCachedData->length, Resource::CacheLo cally); 148 resource->setCachedMetadata(streamer->cachedDataType(), reinterpret_ cast<const char*>(newCachedData->data), newCachedData->length, Resource::CacheLo cally);
131 } 149 }
132 } else if (!resource || !resource->url().protocolIsInHTTPFamily() || code->L ength() < 1024) { 150 } else if (!resource || !resource->url().protocolIsInHTTPFamily() || code->L ength() < 1024) {
133 v8::ScriptCompiler::Source source(code, origin); 151 v8::ScriptCompiler::Source source(code, origin);
134 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions); 152 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions);
135 } else { 153 } else {
154 bool compressed = false;
155 Resource::MetadataCacheType cacheType = Resource::CacheLocally;
156 v8::ScriptCompiler::CompileOptions consumeOption = v8::ScriptCompiler::k ConsumeParserCache;
157 v8::ScriptCompiler::CompileOptions produceOption = v8::ScriptCompiler::k ProduceParserCache;
136 switch (cacheOptions) { 158 switch (cacheOptions) {
159 case V8CacheOptionsOff:
160 // Use default.
161 cacheTag = tagForParserCache();
162 break;
137 case V8CacheOptionsParse: 163 case V8CacheOptionsParse:
138 cacheTag = tagForParserCache(); 164 cacheTag = tagForParserCache();
139 script = resource->cachedMetadata(cacheTag) 165 cacheType = Resource::SendToPlatform;
140 ? compileAndConsumeCache(isolate, code, origin, resource, v8::Sc riptCompiler::kConsumeParserCache, cacheTag) 166 consumeOption = v8::ScriptCompiler::kConsumeParserCache;
141 : compileAndProduceCache(isolate, code, origin, resource, v8::Sc riptCompiler::kProduceParserCache, cacheTag, Resource::SendToPlatform); 167 produceOption = v8::ScriptCompiler::kProduceParserCache;
142 break; 168 break;
169 case V8CacheOptionsCodeCompressed:
170 compressed = true;
171 // Fall through.
143 case V8CacheOptionsCode: 172 case V8CacheOptionsCode:
144 cacheTag = tagForCodeCache(); 173 cacheTag = tagForCodeCache();
145 script = resource->cachedMetadata(cacheTag) 174 cacheType = Resource::SendToPlatform;
146 ? compileAndConsumeCache(isolate, code, origin, resource, v8::Sc riptCompiler::kConsumeCodeCache, cacheTag) 175 consumeOption = v8::ScriptCompiler::kConsumeCodeCache;
147 : compileAndProduceCache(isolate, code, origin, resource, v8::Sc riptCompiler::kProduceCodeCache, cacheTag, Resource::SendToPlatform); 176 produceOption = v8::ScriptCompiler::kProduceCodeCache;
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);
158 break; 177 break;
159 } 178 }
179 script = resource->cachedMetadata(cacheTag)
180 ? compileAndConsumeCache(isolate, code, origin, resource, consumeOpt ion, cacheTag, compressed)
181 : compileAndProduceCache(isolate, code, origin, resource, produceOpt ion, cacheTag, cacheType, compressed);
160 } 182 }
161 return script; 183 return script;
162 } 184 }
163 185
164 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) 186 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context)
165 { 187 {
166 if (script.IsEmpty()) 188 if (script.IsEmpty())
167 return v8::Local<v8::Value>(); 189 return v8::Local<v8::Value>();
168 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 190 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
169 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); 191 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
290 { 312 {
291 return StringHash::hash(v8::V8::GetVersion()) * 2; 313 return StringHash::hash(v8::V8::GetVersion()) * 2;
292 } 314 }
293 315
294 unsigned V8ScriptRunner::tagForCodeCache() 316 unsigned V8ScriptRunner::tagForCodeCache()
295 { 317 {
296 return StringHash::hash(v8::V8::GetVersion()) * 2 + 1; 318 return StringHash::hash(v8::V8::GetVersion()) * 2 + 1;
297 } 319 }
298 320
299 } // namespace blink 321 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698