| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/api-natives.h" | 5 #include "src/api-natives.h" |
| 6 #include "src/isolate-inl.h" | 6 #include "src/isolate-inl.h" |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 | 10 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } | 200 } |
| 201 auto object = isolate->factory()->NewJSObject(cons); | 201 auto object = isolate->factory()->NewJSObject(cons); |
| 202 ASSIGN_RETURN_ON_EXCEPTION( | 202 ASSIGN_RETURN_ON_EXCEPTION( |
| 203 isolate, result, ConfigureInstance(isolate, object, info), JSFunction); | 203 isolate, result, ConfigureInstance(isolate, object, info), JSFunction); |
| 204 // TODO(dcarney): is this necessary? | 204 // TODO(dcarney): is this necessary? |
| 205 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); | 205 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); |
| 206 return scope.CloseAndEscape(result); | 206 return scope.CloseAndEscape(result); |
| 207 } | 207 } |
| 208 | 208 |
| 209 | 209 |
| 210 void InstallInCache(Isolate* isolate, int serial_number, | 210 void CacheFunction(Isolate* isolate, Handle<Smi> serial_number, |
| 211 Handle<JSFunction> function) { | 211 Handle<JSFunction> function) { |
| 212 auto cache = isolate->function_cache(); | 212 auto cache = isolate->function_cache(); |
| 213 if (cache->length() <= serial_number) { | 213 auto new_cache = ObjectHashTable::Put(cache, serial_number, function); |
| 214 int new_size; | 214 isolate->native_context()->set_function_cache(*new_cache); |
| 215 if (isolate->next_serial_number() < 50) { | 215 } |
| 216 new_size = 100; | 216 |
| 217 } else { | 217 |
| 218 new_size = 3 * isolate->next_serial_number() / 2; | 218 void UncacheFunction(Isolate* isolate, Handle<Smi> serial_number) { |
| 219 } | 219 auto cache = isolate->function_cache(); |
| 220 cache = FixedArray::CopySize(cache, new_size); | 220 bool was_present = false; |
| 221 isolate->native_context()->set_function_cache(*cache); | 221 auto new_cache = ObjectHashTable::Remove(cache, serial_number, &was_present); |
| 222 } | 222 DCHECK(was_present); |
| 223 cache->set(serial_number, *function); | 223 isolate->native_context()->set_function_cache(*new_cache); |
| 224 } | 224 } |
| 225 | 225 |
| 226 | 226 |
| 227 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, | 227 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, |
| 228 Handle<FunctionTemplateInfo> data, | 228 Handle<FunctionTemplateInfo> data, |
| 229 Handle<Name> name) { | 229 Handle<Name> name) { |
| 230 int serial_number = Smi::cast(data->serial_number())->value(); | 230 auto serial_number = handle(Smi::cast(data->serial_number()), isolate); |
| 231 // Probe cache. | 231 // Probe cache. |
| 232 if (!data->do_not_cache()) { | 232 if (!data->do_not_cache()) { |
| 233 auto cache = isolate->function_cache(); | 233 auto cache = isolate->function_cache(); |
| 234 // Fast case: see if the function has already been instantiated | 234 Object* element = cache->Lookup(serial_number); |
| 235 if (serial_number < cache->length()) { | 235 if (element->IsJSFunction()) { |
| 236 Handle<Object> element = FixedArray::get(cache, serial_number); | 236 return handle(JSFunction::cast(element), isolate); |
| 237 if (element->IsJSFunction()) { | |
| 238 return Handle<JSFunction>::cast(element); | |
| 239 } | |
| 240 } | 237 } |
| 241 } | 238 } |
| 242 // Enter a new scope. Recursion could otherwise create a lot of handles. | 239 // Enter a new scope. Recursion could otherwise create a lot of handles. |
| 243 HandleScope scope(isolate); | 240 HandleScope scope(isolate); |
| 244 Handle<JSObject> prototype; | 241 Handle<JSObject> prototype; |
| 245 if (!data->remove_prototype()) { | 242 if (!data->remove_prototype()) { |
| 246 auto prototype_templ = handle(data->prototype_template(), isolate); | 243 auto prototype_templ = handle(data->prototype_template(), isolate); |
| 247 if (prototype_templ->IsUndefined()) { | 244 if (prototype_templ->IsUndefined()) { |
| 248 prototype = isolate->factory()->NewJSObject(isolate->object_function()); | 245 prototype = isolate->factory()->NewJSObject(isolate->object_function()); |
| 249 } else { | 246 } else { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 272 isolate, JSObject::SetPrototype(prototype, parent_prototype, false), | 269 isolate, JSObject::SetPrototype(prototype, parent_prototype, false), |
| 273 JSFunction); | 270 JSFunction); |
| 274 } | 271 } |
| 275 } | 272 } |
| 276 auto function = ApiNatives::CreateApiFunction( | 273 auto function = ApiNatives::CreateApiFunction( |
| 277 isolate, data, prototype, ApiNatives::JavaScriptObjectType); | 274 isolate, data, prototype, ApiNatives::JavaScriptObjectType); |
| 278 if (!name.is_null() && name->IsString()) { | 275 if (!name.is_null() && name->IsString()) { |
| 279 function->shared()->set_name(*name); | 276 function->shared()->set_name(*name); |
| 280 } | 277 } |
| 281 if (!data->do_not_cache()) { | 278 if (!data->do_not_cache()) { |
| 282 // Cache the function to limit recursion. | 279 // Cache the function. |
| 283 InstallInCache(isolate, serial_number, function); | 280 CacheFunction(isolate, serial_number, function); |
| 284 } | 281 } |
| 285 auto result = ConfigureInstance(isolate, function, data); | 282 auto result = ConfigureInstance(isolate, function, data); |
| 286 if (result.is_null()) { | 283 if (result.is_null()) { |
| 287 // uncache on error. | 284 // Uncache on error. |
| 288 if (!data->do_not_cache()) { | 285 if (!data->do_not_cache()) { |
| 289 auto cache = isolate->function_cache(); | 286 UncacheFunction(isolate, serial_number); |
| 290 cache->set(serial_number, isolate->heap()->undefined_value()); | |
| 291 } | 287 } |
| 292 return MaybeHandle<JSFunction>(); | 288 return MaybeHandle<JSFunction>(); |
| 293 } | 289 } |
| 294 return scope.CloseAndEscape(function); | 290 return scope.CloseAndEscape(function); |
| 295 } | 291 } |
| 296 | 292 |
| 297 | 293 |
| 298 class InvokeScope { | 294 class InvokeScope { |
| 299 public: | 295 public: |
| 300 explicit InvokeScope(Isolate* isolate) | 296 explicit InvokeScope(Isolate* isolate) |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); | 575 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); |
| 580 JSObject::SetAccessor(result, accessor).Assert(); | 576 JSObject::SetAccessor(result, accessor).Assert(); |
| 581 } | 577 } |
| 582 | 578 |
| 583 DCHECK(result->shared()->IsApiFunction()); | 579 DCHECK(result->shared()->IsApiFunction()); |
| 584 return result; | 580 return result; |
| 585 } | 581 } |
| 586 | 582 |
| 587 } // namespace internal | 583 } // namespace internal |
| 588 } // namespace v8 | 584 } // namespace v8 |
| OLD | NEW |