From 06869e752e039e122d9135fb71ab2aa28a5dc6cb Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Wed, 10 Apr 2013 05:46:09 +0000 Subject: [PATCH] MIPS: Always check global property cells for readonliness before storing. Add check when the global object is the last in the chain. Port r14173 (97683cb2) BUG= Review URL: https://codereview.chromium.org/13887004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14194 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/stub-cache-mips.cc | 57 ++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index b6bf924..cfa43a0 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -410,6 +410,25 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, } +// Generate code to check that a global property cell is empty. Create +// the property cell at compilation time if no cell exists for the +// property. +static void GenerateCheckPropertyCell(MacroAssembler* masm, + Handle global, + Handle name, + Register scratch, + Label* miss) { + Handle cell = + GlobalObject::EnsurePropertyCell(global, name); + ASSERT(cell->value()->IsTheHole()); + __ li(scratch, Operand(cell)); + __ lw(scratch, + FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); + __ LoadRoot(at, Heap::kTheHoleValueRootIndex); + __ Branch(miss, ne, scratch, Operand(at)); +} + + // Generate StoreField code, value is passed in a0 register. // After executing generated code, the receiver_reg and name_reg // may be clobbered. @@ -458,12 +477,18 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm, // If no property was found, and the holder (the last object in the // prototype chain) is in slow mode, we need to do a negative lookup on the // holder. - if (lookup->holder() == *object && - !holder->HasFastProperties() && - !holder->IsJSGlobalProxy() && - !holder->IsJSGlobalObject()) { - GenerateDictionaryNegativeLookup( - masm, miss_restore_name, holder_reg, name, scratch1, scratch2); + if (lookup->holder() == *object) { + if (holder->IsJSGlobalObject()) { + GenerateCheckPropertyCell( + masm, + Handle(GlobalObject::cast(holder)), + name, + scratch1, + miss_restore_name); + } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { + GenerateDictionaryNegativeLookup( + masm, miss_restore_name, holder_reg, name, scratch1, scratch2); + } } } @@ -926,26 +951,6 @@ class CallInterceptorCompiler BASE_EMBEDDED { }; - -// Generate code to check that a global property cell is empty. Create -// the property cell at compilation time if no cell exists for the -// property. -static void GenerateCheckPropertyCell(MacroAssembler* masm, - Handle global, - Handle name, - Register scratch, - Label* miss) { - Handle cell = - GlobalObject::EnsurePropertyCell(global, name); - ASSERT(cell->value()->IsTheHole()); - __ li(scratch, Operand(cell)); - __ lw(scratch, - FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); - __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - __ Branch(miss, ne, scratch, Operand(at)); -} - - // Calls GenerateCheckPropertyCell for each global object in the prototype chain // from object to (but not including) holder. static void GenerateCheckPropertyCells(MacroAssembler* masm, -- 2.7.4