Author: [EMAIL PROTECTED]
Date: Fri Oct 3 02:16:12 2008
New Revision: 420
Modified:
branches/bleeding_edge/src/builtins.cc
branches/bleeding_edge/src/builtins.h
branches/bleeding_edge/src/date-delay.js
branches/bleeding_edge/src/handles.cc
branches/bleeding_edge/src/ic-arm.cc
branches/bleeding_edge/src/ic-ia32.cc
branches/bleeding_edge/src/ic.cc
branches/bleeding_edge/src/ic.h
branches/bleeding_edge/src/stub-cache-arm.cc
branches/bleeding_edge/src/stub-cache-ia32.cc
Log:
- Added fast case for extending the JSObject properties storage.
- Changed date to compute local_time_offset at load time.
Review URL: http://codereview.chromium.org/6441
Modified: branches/bleeding_edge/src/builtins.cc
==============================================================================
--- branches/bleeding_edge/src/builtins.cc (original)
+++ branches/bleeding_edge/src/builtins.cc Fri Oct 3 02:16:12 2008
@@ -561,6 +561,10 @@
}
+static void Generate_StoreIC_ExtendStorage(MacroAssembler* masm) {
+ StoreIC::GenerateExtendStorage(masm);
+}
+
static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
StoreIC::GenerateMegamorphic(masm);
}
Modified: branches/bleeding_edge/src/builtins.h
==============================================================================
--- branches/bleeding_edge/src/builtins.h (original)
+++ branches/bleeding_edge/src/builtins.h Fri Oct 3 02:16:12 2008
@@ -62,6 +62,8 @@
V(StoreIC_Miss, BUILTIN, UNINITIALIZED) \
V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED) \
\
+ V(StoreIC_ExtendStorage, BUILTIN, UNINITIALIZED) \
+ \
V(LoadIC_Initialize, LOAD_IC, UNINITIALIZED) \
V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC) \
V(LoadIC_Normal, LOAD_IC, MONOMORPHIC) \
Modified: branches/bleeding_edge/src/date-delay.js
==============================================================================
--- branches/bleeding_edge/src/date-delay.js (original)
+++ branches/bleeding_edge/src/date-delay.js Fri Oct 3 02:16:12 2008
@@ -36,7 +36,6 @@
// changes to these properties.
const $Date = global.Date;
-
// ECMA 262 - 15.9.1.2
function Day(time) {
return $floor(time/msPerDay);
@@ -127,17 +126,6 @@
return TimeClip(MakeDate(day, TimeWithinDay(t)));
}
-
-var local_time_offset;
-
-function LocalTimeOffset() {
- if (IS_UNDEFINED(local_time_offset)) {
- local_time_offset = %DateLocalTimeOffset();
- }
- return local_time_offset;
-}
-
-
var daylight_cache_time = $NaN;
var daylight_cache_offset;
@@ -170,16 +158,17 @@
return Modulo(Day(time) + 4, 7);
}
+var local_time_offset = %DateLocalTimeOffset();
function LocalTime(time) {
if ($isNaN(time)) return time;
- return time + LocalTimeOffset() + DaylightSavingsOffset(time);
+ return time + local_time_offset + DaylightSavingsOffset(time);
}
function UTC(time) {
if ($isNaN(time)) return time;
- var tmp = time - LocalTimeOffset();
+ var tmp = time - local_time_offset;
return tmp - DaylightSavingsOffset(tmp);
}
@@ -530,7 +519,7 @@
function LocalTimezoneString(time) {
- var timezoneOffset = (LocalTimeOffset() + DaylightSavingsOffset(time)) /
msPerMinute;
+ var timezoneOffset = (local_time_offset + DaylightSavingsOffset(time)) /
msPerMinute;
var sign = (timezoneOffset >= 0) ? 1 : -1;
var hours = $floor((sign * timezoneOffset)/60);
var min = $floor((sign * timezoneOffset)%60);
Modified: branches/bleeding_edge/src/handles.cc
==============================================================================
--- branches/bleeding_edge/src/handles.cc (original)
+++ branches/bleeding_edge/src/handles.cc Fri Oct 3 02:16:12 2008
@@ -86,21 +86,26 @@
}
-void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo>
shared,
- int estimate) {
+static int ExpectedNofPropertiesFromEstimate(int estimate) {
// TODO(1231235): We need dynamic feedback to estimate the number
// of expected properties in an object. The static hack below
// is barely a solution.
- shared->set_expected_nof_properties(estimate + 2);
+ if (estimate == 0) return 4;
+ return estimate + 2;
+}
+
+
+void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo>
shared,
+ int estimate) {
+ shared->set_expected_nof_properties(
+ ExpectedNofPropertiesFromEstimate(estimate));
}
void SetExpectedNofPropertiesFromEstimate(Handle<JSFunction> func,
int estimate) {
- // TODO(1231235): We need dynamic feedback to estimate the number
- // of expected properties in an object. The static hack below
- // is barely a solution.
- SetExpectedNofProperties(func, estimate + 2);
+ SetExpectedNofProperties(
+ func, ExpectedNofPropertiesFromEstimate(estimate));
}
Modified: branches/bleeding_edge/src/ic-arm.cc
==============================================================================
--- branches/bleeding_edge/src/ic-arm.cc (original)
+++ branches/bleeding_edge/src/ic-arm.cc Fri Oct 3 02:16:12 2008
@@ -539,9 +539,6 @@
}
-// Defined in ic.cc.
-Object* StoreIC_Miss(Arguments args);
-
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : value
@@ -557,6 +554,22 @@
// Cache miss: Jump to runtime.
Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
+}
+
+
+void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- r0 : value
+ // -- r2 : name
+ // -- lr : return address
+ // -- [sp] : receiver
+ // -----------------------------------
+
+ __ ldr(r3, MemOperand(sp)); // copy receiver
+ __ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
+
+ // Perform tail call to the entry.
+ __
TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ExtendStorage)), 3);
}
Modified: branches/bleeding_edge/src/ic-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ic-ia32.cc (original)
+++ branches/bleeding_edge/src/ic-ia32.cc Fri Oct 3 02:16:12 2008
@@ -669,9 +669,6 @@
}
-// Defined in ic.cc.
-Object* StoreIC_Miss(Arguments args);
-
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : value
@@ -687,6 +684,25 @@
// Cache miss: Jump to runtime.
Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
+}
+
+
+void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- eax : value
+ // -- ecx : transition map
+ // -- esp[0] : return address
+ // -- esp[4] : receiver
+ // -----------------------------------
+
+ // Move the return address below the arguments.
+ __ pop(ebx);
+ __ push(Operand(esp, 0));
+ __ push(ecx);
+ __ push(eax);
+ __ push(ebx);
+ // Perform tail call to the entry.
+ __
TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ExtendStorage)), 3);
}
Modified: branches/bleeding_edge/src/ic.cc
==============================================================================
--- branches/bleeding_edge/src/ic.cc (original)
+++ branches/bleeding_edge/src/ic.cc Fri Oct 3 02:16:12 2008
@@ -874,10 +874,8 @@
}
case MAP_TRANSITION: {
if (lookup->GetAttributes() != NONE) return;
- if (receiver->map()->unused_property_fields() == 0) return;
HandleScope scope;
- ASSERT(type == MAP_TRANSITION &&
- (receiver->map()->unused_property_fields() > 0));
+ ASSERT(type == MAP_TRANSITION);
Handle<Map> transition(lookup->GetTransitionMap());
int index = transition->PropertyIndexFor(*name);
code = StubCache::ComputeStoreField(*name, *receiver, index,
*transition);
@@ -906,7 +904,8 @@
if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
set_target(Code::cast(code));
} else if (state == MONOMORPHIC) {
- set_target(megamorphic_stub());
+ // Only move to mega morphic if the target changes.
+ if (target() != Code::cast(code)) set_target(megamorphic_stub());
}
#ifdef DEBUG
@@ -996,10 +995,8 @@
}
case MAP_TRANSITION: {
if (lookup->GetAttributes() == NONE) {
- if (receiver->map()->unused_property_fields() == 0) return;
HandleScope scope;
- ASSERT(type == MAP_TRANSITION &&
- (receiver->map()->unused_property_fields() > 0));
+ ASSERT(type == MAP_TRANSITION);
Handle<Map> transition(lookup->GetTransitionMap());
int index = transition->PropertyIndexFor(*name);
code = StubCache::ComputeKeyedStoreField(*name, *receiver,
@@ -1112,6 +1109,40 @@
IC::State state = IC::StateFrom(ic.target(), args[0]);
return ic.Store(state, args.at<Object>(0), args.at<String>(1),
args.at<Object>(2));
+}
+
+
+// Extend storage is called in a store inline cache when
+// it is necessary to extend the properties array of a
+// JSObject.
+Object* StoreIC_ExtendStorage(Arguments args) {
+ NoHandleAllocation na;
+ ASSERT(args.length() == 3);
+
+ // Convert the parameters
+ JSObject* object = JSObject::cast(args[0]);
+ Map* transition = Map::cast(args[1]);
+ Object* value = args[2];
+
+ // Check the object has run out out property space.
+ ASSERT(object->HasFastProperties());
+ ASSERT(object->map()->unused_property_fields() == 0);
+
+ // Expand the properties array.
+ FixedArray* old_storage = object->properties();
+ int new_unused = transition->unused_property_fields();
+ int new_size = old_storage->length() + new_unused + 1;
+ Object* result = old_storage->CopySize(new_size);
+ if (result->IsFailure()) return result;
+ FixedArray* new_storage = FixedArray::cast(result);
+ new_storage->set(old_storage->length(), value);
+
+ // Set the new property value and do the map tranistion.
+ object->set_properties(new_storage);
+ object->set_map(transition);
+
+ // Return the stored value.
+ return value;
}
Modified: branches/bleeding_edge/src/ic.h
==============================================================================
--- branches/bleeding_edge/src/ic.h (original)
+++ branches/bleeding_edge/src/ic.h Fri Oct 3 02:16:12 2008
@@ -39,6 +39,7 @@
ICU(KeyedLoadIC_Miss) \
ICU(CallIC_Miss) \
ICU(StoreIC_Miss) \
+ ICU(StoreIC_ExtendStorage) \
ICU(KeyedStoreIC_Miss) \
/* Utilities for IC stubs. */ \
ICU(LoadCallbackProperty) \
@@ -294,6 +295,7 @@
static void GenerateInitialize(MacroAssembler* masm);
static void GenerateMiss(MacroAssembler* masm);
static void GenerateMegamorphic(MacroAssembler* masm);
+ static void GenerateExtendStorage(MacroAssembler* masm);
private:
static void Generate(MacroAssembler* masm, const ExternalReference& f);
Modified: branches/bleeding_edge/src/stub-cache-arm.cc
==============================================================================
--- branches/bleeding_edge/src/stub-cache-arm.cc (original)
+++ branches/bleeding_edge/src/stub-cache-arm.cc Fri Oct 3 02:16:12 2008
@@ -416,10 +416,18 @@
// Perform map transition for the receiver if necessary.
if (transition != NULL) {
- // Update the map of the object; no write barrier updating is
- // needed because the map is never in new space.
- __ mov(ip, Operand(Handle<Map>(transition)));
- __ str(ip, FieldMemOperand(r3, HeapObject::kMapOffset));
+ if (object->map()->unused_property_fields() == 0) {
+ // The properties must be extended before we can store the value.
+ // We jump to a runtime call that extends the propeties array.
+ __ mov(r2, Operand(Handle<Map>(transition)));
+ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_ExtendStorage));
+ __ Jump(ic, RelocInfo::CODE_TARGET);
+ } else {
+ // Update the map of the object; no write barrier updating is
+ // needed because the map is never in new space.
+ __ mov(ip, Operand(Handle<Map>(transition)));
+ __ str(ip, FieldMemOperand(r3, HeapObject::kMapOffset));
+ }
}
// Write to the properties array.
Modified: branches/bleeding_edge/src/stub-cache-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/stub-cache-ia32.cc (original)
+++ branches/bleeding_edge/src/stub-cache-ia32.cc Fri Oct 3 02:16:12 2008
@@ -436,10 +436,18 @@
// Perform map transition for the receiver if necessary.
if (transition != NULL) {
- // Update the map of the object; no write barrier updating is
- // needed because the map is never in new space.
- __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset),
- Immediate(Handle<Map>(transition)));
+ if (object->map()->unused_property_fields() == 0) {
+ // The properties must be extended before we can store the value.
+ // We jump to a runtime call that extends the propeties array.
+ __ mov(Operand(ecx), Immediate(Handle<Map>(transition)));
+ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_ExtendStorage));
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+ } else {
+ // Update the map of the object; no write barrier updating is
+ // needed because the map is never in new space.
+ __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset),
+ Immediate(Handle<Map>(transition)));
+ }
}
// Write to the properties array.
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---