From: feng@chromium.org Date: Tue, 21 Oct 2008 20:11:50 +0000 (+0000) Subject: No more failures than before. It is ready to be reviewed. X-Git-Tag: upstream/4.7.83~25158 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=202dedbdb3e01b0ad073b2ec987a451f72f12d40;p=platform%2Fupstream%2Fv8.git No more failures than before. It is ready to be reviewed. Review URL: http://codereview.chromium.org/7420 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@544 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/builtins-arm.cc b/src/builtins-arm.cc index 68b5f1d..c1b654f 100644 --- a/src/builtins-arm.cc +++ b/src/builtins-arm.cc @@ -333,11 +333,12 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { __ LeaveInternalFrame(); __ b(&patch_receiver); - // Use the global object from the called function as the receiver. + // Use the global receiver object from the called function as the receiver. __ bind(&use_global_receiver); const int kGlobalIndex = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; __ ldr(r2, FieldMemOperand(cp, kGlobalIndex)); + __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); __ bind(&patch_receiver); __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2)); @@ -472,10 +473,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); __ b(&push_receiver); - // Use the current global object as the receiver. + // Use the current global receiver object as the receiver. __ bind(&use_global_receiver); - __ ldr(r0, FieldMemOperand(cp, Context::kHeaderSize + - Context::GLOBAL_INDEX * kPointerSize)); + const int kGlobalOffset = + Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; + __ ldr(r0, FieldMemOperand(cp, kGlobalOffset)); + __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); // Push the receiver. // r0: receiver diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index 92206dd..f89525d 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -415,6 +415,13 @@ void CodeGenerator::LoadGlobal() { } +void CodeGenerator::LoadGlobalReceiver(Register s) { + __ ldr(s, ContextOperand(cp, Context::GLOBAL_INDEX)); + __ ldr(s, FieldMemOperand(s, GlobalObject::kGlobalReceiverOffset)); + __ push(s); +} + + // TODO(1241834): Get rid of this function in favor of just using Load, now // that we have the INSIDE_TYPEOF typeof state. => Need to handle global // variables w/o reference errors elsewhere. @@ -2220,7 +2227,10 @@ void CodeGenerator::VisitCall(Call* node) { // Push the name of the function and the receiver onto the stack. __ mov(r0, Operand(var->name())); __ push(r0); - LoadGlobal(); + + // TODO(120): use JSGlobalObject for function lookup and inline cache, + // and use global proxy as 'this' for invocation. + LoadGlobalReceiver(r0); // Load the arguments. for (int i = 0; i < args->length(); i++) Load(args->at(i)); @@ -2308,7 +2318,10 @@ void CodeGenerator::VisitCall(Call* node) { // Load the function. Load(function); // Pass the global object as the receiver. - LoadGlobal(); + + // TODO(120): use JSGlobalObject for function lookup and inline cache, + // and use global proxy as 'this' for invocation. + LoadGlobalReceiver(r0); // Call the function. CallWithArguments(args, node->position()); __ push(r0); @@ -2328,7 +2341,7 @@ void CodeGenerator::VisitCallNew(CallNew* node) { // Compute function to call and use the global object as the // receiver. Load(node->expression()); - LoadGlobal(); + LoadGlobalReceiver(r0); // Push the arguments ("left-to-right") on the stack. ZoneList* args = node->arguments(); @@ -2873,12 +2886,11 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { // inlining a null check instead of calling the (very) general // runtime routine for checking equality. - bool left_is_null = - left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); - bool right_is_null = - right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); - if (op == Token::EQ || op == Token::EQ_STRICT) { + bool left_is_null = + left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); + bool right_is_null = + right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); // The 'null' value is only equal to 'null' or 'undefined'. if (left_is_null || right_is_null) { Load(left_is_null ? right : left); diff --git a/src/codegen-arm.h b/src/codegen-arm.h index 5342b5a..0300f81 100644 --- a/src/codegen-arm.h +++ b/src/codegen-arm.h @@ -225,6 +225,7 @@ class CodeGenerator: public Visitor { bool force_cc); void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF); void LoadGlobal(); + void LoadGlobalReceiver(Register scratch); // Read a value from a slot and leave it on top of the expression stack. void LoadFromSlot(Slot* slot, TypeofState typeof_state); diff --git a/src/ic-arm.cc b/src/ic-arm.cc index 5a60322..d08e7b7 100644 --- a/src/ic-arm.cc +++ b/src/ic-arm.cc @@ -366,7 +366,7 @@ void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); // Check for access to global object (unlikely). - __ cmp(r0, Operand(JS_GLOBAL_OBJECT_TYPE)); + __ cmp(r0, Operand(JS_GLOBAL_PROXY_TYPE)); __ b(eq, &global); // Search the dictionary placing the result in r1. @@ -392,7 +392,7 @@ void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { // Global object access: Check access rights. __ bind(&global); - __ CheckAccessGlobal(r1, r0, &miss); + __ CheckAccessGlobalProxy(r1, r0, &miss); __ b(&probe); // Cache miss: Jump to runtime. @@ -482,7 +482,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); // Check for access to global object (unlikely). - __ cmp(r1, Operand(JS_GLOBAL_OBJECT_TYPE)); + __ cmp(r1, Operand(JS_GLOBAL_PROXY_TYPE)); __ b(eq, &global); @@ -492,7 +492,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // Global object access: Check access rights. __ bind(&global); - __ CheckAccessGlobal(r0, r1, &miss); + __ CheckAccessGlobalProxy(r0, r1, &miss); __ b(&probe); // Cache miss: Restore receiver from stack and jump to runtime. diff --git a/src/macro-assembler-arm.cc b/src/macro-assembler-arm.cc index c7139f4..92666af 100644 --- a/src/macro-assembler-arm.cc +++ b/src/macro-assembler-arm.cc @@ -593,7 +593,7 @@ Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg, // Only global objects and objects that do not require access // checks are allowed in stubs. - ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded()); + ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); // Get the map of the current object. ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); @@ -605,8 +605,8 @@ Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg, // Check access rights to the global object. This has to happen // after the map check so that we know that the object is // actually a global object. - if (object->IsJSGlobalObject()) { - CheckAccessGlobal(reg, scratch, miss); + if (object->IsJSGlobalProxy()) { + CheckAccessGlobalProxy(reg, scratch, miss); // Restore scratch register to be the map of the object. In the // new space case below, we load the prototype from the map in // the scratch register. @@ -639,38 +639,73 @@ Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg, // Perform security check for access to the global object and return // the holder register. ASSERT(object == holder); - ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded()); - if (object->IsJSGlobalObject()) { - CheckAccessGlobal(reg, scratch, miss); + ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); + if (object->IsJSGlobalProxy()) { + CheckAccessGlobalProxy(reg, scratch, miss); } return reg; } -void MacroAssembler::CheckAccessGlobal(Register holder_reg, - Register scratch, - Label* miss) { +void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, + Register scratch, + Label* miss) { + Label same_contexts; + ASSERT(!holder_reg.is(scratch)); + ASSERT(!holder_reg.is(ip)); + ASSERT(!scratch.is(ip)); - // Load the security context. - mov(scratch, Operand(Top::security_context_address())); - ldr(scratch, MemOperand(scratch)); - // In debug mode, make sure the security context is set. + // Load current lexical context from the stack frame. + ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); + // In debug mode, make sure the lexical context is set. if (kDebug) { cmp(scratch, Operand(0)); - Check(ne, "we should not have an empty security context"); + Check(ne, "we should not have an empty lexical context"); } - // Load the global object of the security context. + // Load the global context of the current context. int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; ldr(scratch, FieldMemOperand(scratch, offset)); + ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset)); + + // Check the context is a global context. + if (FLAG_debug_code) { + // Read the first word and compare to the global_context_map. + ldr(ip, FieldMemOperand(scratch, HeapObject::kMapOffset)); + cmp(ip, Operand(Factory::global_context_map())); + Check(eq, "JSGlobalObject::global_context should be a global context."); + } + + // Check if both contexts are the same. + ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset)); + cmp(scratch, Operand(ip)); + b(eq, &same_contexts); + + // Check the context is a global context. + if (FLAG_debug_code) { + cmp(ip, Operand(Factory::null_value())); + Check(ne, "JSGlobalProxy::context() should not be null."); + + ldr(ip, FieldMemOperand(ip, HeapObject::kMapOffset)); + cmp(ip, Operand(Factory::global_context_map())); + Check(eq, "JSGlobalObject::global_context should be a global context."); + // Restore ip to holder's context. + ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset)); + } + // Check that the security token in the calling global object is // compatible with the security token in the receiving global // object. - ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kSecurityTokenOffset)); - ldr(ip, FieldMemOperand(holder_reg, JSGlobalObject::kSecurityTokenOffset)); + int token_offset = Context::kHeaderSize + + Context::SECURITY_TOKEN_INDEX * kPointerSize; + + ldr(scratch, FieldMemOperand(scratch, token_offset)); + ldr(ip, FieldMemOperand(ip, token_offset)); cmp(scratch, Operand(ip)); b(ne, miss); + + bind(&same_contexts); } diff --git a/src/macro-assembler-arm.h b/src/macro-assembler-arm.h index d1a4a44..956cd71 100644 --- a/src/macro-assembler-arm.h +++ b/src/macro-assembler-arm.h @@ -176,7 +176,9 @@ class MacroAssembler: public Assembler { // Generate code for checking access rights - used for security checks // on access to global objects across environments. The holder register // is left untouched, whereas both scratch registers are clobbered. - void CheckAccessGlobal(Register holder_reg, Register scratch, Label* miss); + void CheckAccessGlobalProxy(Register holder_reg, + Register scratch, + Label* miss); // --------------------------------------------------------------------------- diff --git a/src/stub-cache-arm.cc b/src/stub-cache-arm.cc index 5bcc6b0..085c04a 100644 --- a/src/stub-cache-arm.cc +++ b/src/stub-cache-arm.cc @@ -420,13 +420,13 @@ Object* StoreStubCompiler::CompileStoreField(JSObject* object, __ b(ne, &miss); // Perform global security token check if needed. - if (object->IsJSGlobalObject()) { - __ CheckAccessGlobal(r3, r1, &miss); + if (object->IsJSGlobalProxy()) { + __ CheckAccessGlobalProxy(r3, r1, &miss); } // Stub never generated for non-global objects that require access // checks. - ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded()); + ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); // Perform map transition for the receiver if necessary. if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { @@ -522,13 +522,13 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object, __ b(ne, &miss); // Perform global security token check if needed. - if (object->IsJSGlobalObject()) { - __ CheckAccessGlobal(r3, r1, &miss); + if (object->IsJSGlobalProxy()) { + __ CheckAccessGlobalProxy(r3, r1, &miss); } // Stub never generated for non-global objects that require access // checks. - ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded()); + ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); __ ldr(ip, MemOperand(sp)); // receiver __ push(ip); @@ -578,13 +578,13 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, __ b(ne, &miss); // Perform global security token check if needed. - if (receiver->IsJSGlobalObject()) { - __ CheckAccessGlobal(r3, r1, &miss); + if (receiver->IsJSGlobalProxy()) { + __ CheckAccessGlobalProxy(r3, r1, &miss); } // Stub never generated for non-global objects that require access // checks. - ASSERT(receiver->IsJSGlobalObject() || !receiver->IsAccessCheckNeeded()); + ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); __ ldr(ip, MemOperand(sp)); // receiver __ push(ip);