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

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

Issue 432273004: Implement Blink-side changes to enable V8 code caching. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix very silly bug that causes an unitialized field and a CHECK fail at startup. Created 6 years, 4 months 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
« no previous file with comments | « Source/bindings/core/v8/V8ScriptRunner.h ('k') | Source/core/fetch/Resource.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // If we are already handling a recursion level error, we should 55 // If we are already handling a recursion level error, we should
56 // not invoke v8::Function::Call. 56 // not invoke v8::Function::Call.
57 return v8::Undefined(isolate); 57 return v8::Undefined(isolate);
58 } 58 }
59 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true); 59 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true);
60 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0); 60 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0);
61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false); 61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false);
62 return result; 62 return result;
63 } 63 }
64 64
65 // Make a decision on whether we want to use V8 caching and how.
66 // dataType, produceOption, consumeOption are out parameters.
67 bool CacheDecider(
68 const v8::Handle<v8::String> code,
69 const ScriptResource* resource,
70 V8CacheOptions cacheOptions,
71 unsigned* dataType,
72 v8::ScriptCompiler::CompileOptions* compileOption,
73 bool* produce)
74 {
75 if (!resource || !resource->url().protocolIsInHTTPFamily() || code->Length() < 1024)
76 cacheOptions = V8CacheOptionsOff;
77
78 bool useCache = false;
79 switch (cacheOptions) {
80 case V8CacheOptionsOff:
81 *compileOption = v8::ScriptCompiler::kNoCompileOptions;
82 useCache = false;
83 break;
84 case V8CacheOptionsParse:
85 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2;
86 *produce = !resource->cachedMetadata(*dataType);
87 *compileOption = *produce ? v8::ScriptCompiler::kProduceParserCache : v8 ::ScriptCompiler::kConsumeParserCache;
88 useCache = true;
89 break;
90 case V8CacheOptionsCode:
91 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2 + 1;
92 *produce = !resource->cachedMetadata(*dataType);
93 *compileOption = *produce ? v8::ScriptCompiler::kProduceCodeCache : v8:: ScriptCompiler::kConsumeCodeCache;
94 useCache = true;
95 break;
96 }
97 return useCache;
98 }
99
65 } // namespace 100 } // namespace
66 101
67 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus) 102 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions)
68 { 103 {
69 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus); 104 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus, cacheOptions);
70 } 105 }
71 106
72 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, v8::Isolate* isolate, AccessControlStatus corsStatus) 107 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOptions)
73 { 108 {
74 // A pseudo-randomly chosen ID used to store and retrieve V8 ScriptData from
75 // the ScriptResource. If the format changes, this ID should be changed too.
76 static const unsigned dataTypeID = 0xECC13BD7;
77
78 // Very small scripts are not worth the effort to store cached data.
79 static const int minLengthForCachedData = 1024;
80
81 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); 109 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8());
82 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); 110 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile");
83 111
84 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at 112 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
85 // 1, whereas v8 starts at 0. 113 // 1, whereas v8 starts at 0.
86 v8::Handle<v8::String> name = v8String(isolate, fileName); 114 v8::Handle<v8::String> name = v8String(isolate, fileName);
87 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt()); 115 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt());
88 v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPositi on.m_column.zeroBasedInt()); 116 v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPositi on.m_column.zeroBasedInt());
89 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate); 117 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate);
90 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); 118 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin);
91 119
92 v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kNoCompileO ptions; 120 // V8 supports several forms of caching. Decide on the cache mode and call
93 OwnPtr<v8::ScriptCompiler::CachedData> cachedData; 121 // ScriptCompiler::Compile with suitable options.
94 if (resource) { 122 unsigned dataTypeID = 0;
95 CachedMetadata* cachedMetadata = resource->cachedMetadata(dataTypeID); 123 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions;
96 if (cachedMetadata) { 124 bool produce;
97 // Ownership of the buffer is not transferred to CachedData. 125 v8::Local<v8::Script> script;
98 cachedData = adoptPtr(new v8::ScriptCompiler::CachedData(reinterpret _cast<const uint8_t*>(cachedMetadata->data()), cachedMetadata->size())); 126 if (CacheDecider(code, resource, cacheOptions, &dataTypeID, &compileOption, &produce)) {
99 } else if (code->Length() >= minLengthForCachedData) { 127 if (produce) {
100 options = v8::ScriptCompiler::kProduceDataToCache; 128 // Produce new cache data:
129 v8::ScriptCompiler::Source source(code, origin);
130 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption );
131 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedD ata();
132 if (cachedData) {
133 resource->clearCachedMetadata();
134 resource->setCachedMetadata(
135 dataTypeID,
136 reinterpret_cast<const char*>(cachedData->data),
137 cachedData->length);
138 }
139 } else {
140 // Consume existing cache data:
141 CachedMetadata* cachedMetadata = resource->cachedMetadata(dataTypeID );
142 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler: :CachedData(
143 reinterpret_cast<const uint8_t*>(cachedMetadata->data()),
144 cachedMetadata->size(),
145 v8::ScriptCompiler::CachedData::BufferNotOwned);
146 v8::ScriptCompiler::Source source(code, origin, cachedData);
147 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption );
101 } 148 }
102 } 149 } else {
103 // source takes ownership of cachedData. 150 // No caching:
104 v8::ScriptCompiler::Source source(code, origin, cachedData.leakPtr()); 151 v8::ScriptCompiler::Source source(code, origin);
105 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options); 152 script = v8::ScriptCompiler::Compile(
106 if (options == v8::ScriptCompiler::kProduceDataToCache) { 153 isolate, &source, v8::ScriptCompiler::kNoCompileOptions);
107 const v8::ScriptCompiler::CachedData* newCachedData = source.GetCachedDa ta();
108 if (newCachedData) {
109 // Ownership of the buffer is not transferred; source's cachedData c ontinues to own it.
110 resource->setCachedMetadata(dataTypeID, reinterpret_cast<const char* >(newCachedData->data), newCachedData->length);
111 }
112 } 154 }
113 return script; 155 return script;
114 } 156 }
115 157
116 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc ript, ExecutionContext* context, v8::Isolate* isolate) 158 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc ript, ExecutionContext* context, v8::Isolate* isolate)
117 { 159 {
118 if (script.IsEmpty()) 160 if (script.IsEmpty())
119 return v8::Local<v8::Value>(); 161 return v8::Local<v8::Value>();
120 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 162 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
121 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); 163 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName())));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 { 258 {
217 TRACE_EVENT0("v8", "v8.newInstance"); 259 TRACE_EVENT0("v8", "v8.newInstance");
218 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 260 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
219 V8RecursionScope scope(isolate, context); 261 V8RecursionScope scope(isolate, context);
220 v8::Local<v8::Object> result = function->NewInstance(argc, argv); 262 v8::Local<v8::Object> result = function->NewInstance(argc, argv);
221 crashIfV8IsDead(); 263 crashIfV8IsDead();
222 return result; 264 return result;
223 } 265 }
224 266
225 } // namespace blink 267 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/V8ScriptRunner.h ('k') | Source/core/fetch/Resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698