| Index: src/stub-cache.cc
|
| ===================================================================
|
| --- src/stub-cache.cc (revision 4439)
|
| +++ src/stub-cache.cc (working copy)
|
| @@ -1164,4 +1164,71 @@
|
| }
|
|
|
|
|
| +CallOptimization::CallOptimization(LookupResult* lookup) {
|
| + if (!lookup->IsProperty() || !lookup->IsCacheable() ||
|
| + lookup->type() != CONSTANT_FUNCTION) {
|
| + Initialize(NULL);
|
| + } else {
|
| + // We only optimize constant function calls.
|
| + Initialize(lookup->GetConstantFunction());
|
| + }
|
| +}
|
| +
|
| +CallOptimization::CallOptimization(JSFunction* function) {
|
| + Initialize(function);
|
| +}
|
| +
|
| +
|
| +int CallOptimization::GetPrototypeDepthOfExpectedType(JSObject* object,
|
| + JSObject* holder) const {
|
| + ASSERT(is_simple_api_call_);
|
| + if (expected_receiver_type_ == NULL) return 0;
|
| + int depth = 0;
|
| + while (object != holder) {
|
| + if (object->IsInstanceOf(expected_receiver_type_)) return depth;
|
| + object = JSObject::cast(object->GetPrototype());
|
| + ++depth;
|
| + }
|
| + if (holder->IsInstanceOf(expected_receiver_type_)) return depth;
|
| + return kInvalidProtoDepth;
|
| +}
|
| +
|
| +
|
| +void CallOptimization::Initialize(JSFunction* function) {
|
| + constant_function_ = NULL;
|
| + is_simple_api_call_ = false;
|
| + expected_receiver_type_ = NULL;
|
| + api_call_info_ = NULL;
|
| +
|
| + if (function == NULL || !function->is_compiled()) return;
|
| +
|
| + constant_function_ = function;
|
| + AnalyzePossibleApiFunction(function);
|
| +}
|
| +
|
| +
|
| +void CallOptimization::AnalyzePossibleApiFunction(JSFunction* function) {
|
| + SharedFunctionInfo* sfi = function->shared();
|
| + if (!sfi->IsApiFunction()) return;
|
| + FunctionTemplateInfo* info = sfi->get_api_func_data();
|
| +
|
| + // Require a C++ callback.
|
| + if (info->call_code()->IsUndefined()) return;
|
| + api_call_info_ = CallHandlerInfo::cast(info->call_code());
|
| +
|
| + // Accept signatures that either have no restrictions at all or
|
| + // only have restrictions on the receiver.
|
| + if (!info->signature()->IsUndefined()) {
|
| + SignatureInfo* signature = SignatureInfo::cast(info->signature());
|
| + if (!signature->args()->IsUndefined()) return;
|
| + if (!signature->receiver()->IsUndefined()) {
|
| + expected_receiver_type_ =
|
| + FunctionTemplateInfo::cast(signature->receiver());
|
| + }
|
| + }
|
| +
|
| + is_simple_api_call_ = true;
|
| +}
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|