diff options
Diffstat (limited to 'Source/JavaScriptCore/llint/LLIntSlowPaths.cpp')
-rw-r--r-- | Source/JavaScriptCore/llint/LLIntSlowPaths.cpp | 118 |
1 files changed, 80 insertions, 38 deletions
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index fbf5b8598..74beae98a 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -119,12 +119,20 @@ namespace JSC { namespace LLInt { JSValue __rp_returnValue = (value); \ LLINT_CHECK_EXCEPTION(); \ LLINT_OP(1) = __rp_returnValue; \ - pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \ - JSValue::encode(__rp_returnValue); \ + LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \ LLINT_END_IMPL(); \ } while (false) + +#define LLINT_PROFILE_VALUE(opcode, value) do { \ + pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \ + JSValue::encode(value); \ + } while (false) + #else // ENABLE(VALUE_PROFILER) #define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value) + +#define LLINT_PROFILE_VALUE(opcode, value) do { } while (false) + #endif // ENABLE(VALUE_PROFILER) #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec)) @@ -777,52 +785,84 @@ LLINT_SLOW_PATH_DECL(slow_path_in) LLINT_SLOW_PATH_DECL(slow_path_resolve) { LLINT_BEGIN(); - LLINT_RETURN_PROFILED(op_resolve, JSScope::resolve(exec, exec->codeBlock()->identifier(pc[2].u.operand))); -} + Identifier ident = exec->codeBlock()->identifier(pc[2].u.operand); + ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[3].u.operand); + JSValue result = JSScope::resolve(exec, ident, operations); + ASSERT(operations->size()); + ASSERT(operations == exec->codeBlock()->resolveOperations(pc[3].u.operand)); + switch (operations->data()[0].m_operation) { + case ResolveOperation::GetAndReturnGlobalProperty: + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_property); + break; -LLINT_SLOW_PATH_DECL(slow_path_resolve_skip) -{ - LLINT_BEGIN(); - LLINT_RETURN_PROFILED( - op_resolve_skip, - JSScope::resolveSkip( - exec, - exec->codeBlock()->identifier(pc[2].u.operand), - pc[3].u.operand)); -} + case ResolveOperation::GetAndReturnGlobalVar: + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_var); + break; -LLINT_SLOW_PATH_DECL(slow_path_resolve_global) -{ - LLINT_BEGIN(); - Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand); - LLINT_RETURN_PROFILED(op_resolve_global, JSScope::resolveGlobal(exec, ident, exec->lexicalGlobalObject(), &pc[3].u.structure, &pc[4].u.operand)); -} + case ResolveOperation::SkipTopScopeNode: + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_with_top_scope_check); + break; -LLINT_SLOW_PATH_DECL(slow_path_resolve_global_dynamic) -{ - // FIXME: <rdar://problem/12185487> LLInt resolve_global_dynamic doesn't check intervening scopes for modification - LLINT_BEGIN(); - Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand); - LLINT_RETURN_PROFILED(op_resolve_global_dynamic, JSScope::resolveGlobal(exec, ident, exec->lexicalGlobalObject(), &pc[3].u.structure, &pc[4].u.operand)); + case ResolveOperation::SkipScopes: + if (operations->data()[0].m_scopesToSkip) + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var); + else + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_on_top_scope); + break; + + default: + break; + } + LLINT_RETURN_PROFILED(op_resolve, result); } -LLINT_SLOW_PATH_DECL(slow_path_resolve_for_resolve_global_dynamic) +LLINT_SLOW_PATH_DECL(slow_path_put_to_base) { LLINT_BEGIN(); - LLINT_RETURN_PROFILED(op_resolve_global_dynamic, JSScope::resolve(exec, exec->codeBlock()->identifier(pc[2].u.operand))); + PutToBaseOperation* operation = exec->codeBlock()->putToBaseOperation(pc[4].u.operand); + JSScope::resolvePut(exec, LLINT_OP_C(1).jsValue(), exec->codeBlock()->identifier(pc[2].u.operand), LLINT_OP_C(3).jsValue(), operation); + switch (operation->m_kind) { + case PutToBaseOperation::VariablePut: + pc[0].u.opcode = LLInt::getOpcode(llint_op_put_to_base_variable); + break; + + default: + break; + } + LLINT_END(); } LLINT_SLOW_PATH_DECL(slow_path_resolve_base) { LLINT_BEGIN(); Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand); + ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand); + JSValue result; if (pc[3].u.operand) { - if (JSValue result = JSScope::resolveBase(exec, ident, true)) - LLINT_RETURN(result); - LLINT_THROW(globalData.exception); + result = JSScope::resolveBase(exec, ident, true, operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand)); + if (!result) + LLINT_THROW(globalData.exception); + } else + result = JSScope::resolveBase(exec, ident, false, operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand)); + ASSERT(operations->size()); + switch (operations->data()[0].m_operation) { + case ResolveOperation::ReturnGlobalObjectAsBase: + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_global); + break; + + case ResolveOperation::SkipTopScopeNode: + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope_with_top_scope_check); + break; + + case ResolveOperation::SkipScopes: + pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope); + break; + + default: + break; } - - LLINT_RETURN_PROFILED(op_resolve_base, JSScope::resolveBase(exec, ident, false)); + LLINT_PROFILE_VALUE(op_resolve_base, result); + LLINT_RETURN(result); } LLINT_SLOW_PATH_DECL(slow_path_ensure_property_exists) @@ -839,24 +879,26 @@ LLINT_SLOW_PATH_DECL(slow_path_ensure_property_exists) LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base) { LLINT_BEGIN(); - JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1)); + ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand); + JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand)); LLINT_CHECK_EXCEPTION(); LLINT_OP(2) = result; - // FIXME: technically should have profiling, but we don't do it because the DFG won't use it. + LLINT_PROFILE_VALUE(op_resolve_with_base, result); LLINT_END(); } LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this) { LLINT_BEGIN(); - JSValue result = JSScope::resolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1)); + ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand); + JSValue result = JSScope::resolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations); LLINT_CHECK_EXCEPTION(); LLINT_OP(2) = result; - // FIXME: technically should have profiling, but we don't do it because the DFG won't use it. + LLINT_PROFILE_VALUE(op_resolve_with_this, result); LLINT_END(); } -LLINT_SLOW_PATH_DECL(slow_path_put_global_var_check) +LLINT_SLOW_PATH_DECL(slow_path_init_global_const_check) { LLINT_BEGIN(); CodeBlock* codeBlock = exec->codeBlock(); |