Revision: 22218
Author: [email protected]
Date: Fri Jul 4 16:46:28 2014 UTC
Log: Version 3.28.13.1 (merged r22168, r22170, r22174)
This corresponds to 3.28.9.1, with r22174 added.
MIPS: KeyedLoadIC should have same register spec as LoadIC.
MIPS: Clean up the global object naming madness.
One of the fast cases in JSObject::MigrateFastToFast() should not be taken
if the number of fields did not change.
BUG=chromium:390918
LOG=N
[email protected]
Review URL: https://codereview.chromium.org/368403002
http://code.google.com/p/v8/source/detail?r=22218
Added:
/trunk/test/mjsunit/regress/regress-crbug-390918.js
Modified:
/trunk/src/mips/builtins-mips.cc
/trunk/src/mips/code-stubs-mips.cc
/trunk/src/mips/debug-mips.cc
/trunk/src/mips/full-codegen-mips.cc
/trunk/src/mips/ic-mips.cc
/trunk/src/mips/lithium-codegen-mips.cc
/trunk/src/mips/lithium-mips.cc
/trunk/src/mips/stub-cache-mips.cc
/trunk/src/objects.cc
/trunk/src/objects.h
/trunk/src/version.cc
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-crbug-390918.js Fri Jul 4 16:46:28
2014 UTC
@@ -0,0 +1,18 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function f(scale) {
+ var arr = {a: 1.1};
+
+ for (var i = 0; i < 2; i++) {
+ arr[2 * scale] = 0;
+ }
+}
+
+f({});
+f({});
+%OptimizeFunctionOnNextCall(f);
+f(1004);
=======================================
--- /trunk/src/mips/builtins-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/builtins-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -1092,7 +1092,7 @@
// a1: function
Label shift_arguments;
__ li(t0, Operand(0, RelocInfo::NONE32)); // Indicate regular
JS_FUNCTION.
- { Label convert_to_object, use_global_receiver, patch_receiver;
+ { Label convert_to_object, use_global_proxy, patch_receiver;
// Change context eagerly in case we need the global receiver.
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
@@ -1118,9 +1118,9 @@
__ JumpIfSmi(a2, &convert_to_object, t2);
__ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
- __ Branch(&use_global_receiver, eq, a2, Operand(a3));
+ __ Branch(&use_global_proxy, eq, a2, Operand(a3));
__ LoadRoot(a3, Heap::kNullValueRootIndex);
- __ Branch(&use_global_receiver, eq, a2, Operand(a3));
+ __ Branch(&use_global_proxy, eq, a2, Operand(a3));
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ GetObjectType(a2, a3, a3);
@@ -1139,16 +1139,17 @@
__ sra(a0, a0, kSmiTagSize); // Un-tag.
// Leave internal frame.
}
+
// Restore the function to a1, and the flag to t0.
__ sll(at, a0, kPointerSizeLog2);
__ addu(at, sp, at);
__ lw(a1, MemOperand(at));
- __ li(t0, Operand(0, RelocInfo::NONE32));
- __ Branch(&patch_receiver);
+ __ Branch(USE_DELAY_SLOT, &patch_receiver);
+ __ li(t0, Operand(0, RelocInfo::NONE32)); // In delay slot.
- __ bind(&use_global_receiver);
+ __ bind(&use_global_proxy);
__ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
__ bind(&patch_receiver);
__ sll(at, a0, kPointerSizeLog2);
@@ -1300,7 +1301,7 @@
// Compute the receiver.
// Do not transform the receiver for strict mode functions.
- Label call_to_object, use_global_receiver;
+ Label call_to_object, use_global_proxy;
__ lw(a2, FieldMemOperand(a2,
SharedFunctionInfo::kCompilerHintsOffset));
__ And(t3, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
kSmiTagSize)));
@@ -1313,9 +1314,9 @@
// Compute the receiver in sloppy mode.
__ JumpIfSmi(a0, &call_to_object);
__ LoadRoot(a1, Heap::kNullValueRootIndex);
- __ Branch(&use_global_receiver, eq, a0, Operand(a1));
+ __ Branch(&use_global_proxy, eq, a0, Operand(a1));
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
- __ Branch(&use_global_receiver, eq, a0, Operand(a2));
+ __ Branch(&use_global_proxy, eq, a0, Operand(a2));
// Check if the receiver is already a JavaScript object.
// a0: receiver
@@ -1331,9 +1332,9 @@
__ mov(a0, v0); // Put object in a0 to match other paths to
push_receiver.
__ Branch(&push_receiver);
- __ bind(&use_global_receiver);
+ __ bind(&use_global_proxy);
__ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
- __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
+ __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset));
// Push the receiver.
// a0: receiver
=======================================
--- /trunk/src/mips/code-stubs-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/code-stubs-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -1971,25 +1971,15 @@
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
- Register receiver;
+ Register receiver = LoadIC::ReceiverRegister();
+ Register name = LoadIC::NameRegister();
+
+ ASSERT(kind() == Code::LOAD_IC ||
+ kind() == Code::KEYED_LOAD_IC);
+
if (kind() == Code::KEYED_LOAD_IC) {
- // ----------- S t a t e -------------
- // -- ra : return address
- // -- a0 : key
- // -- a1 : receiver
- // -----------------------------------
- __ Branch(&miss, ne, a0,
+ __ Branch(&miss, ne, name,
Operand(isolate()->factory()->prototype_string()));
- receiver = a1;
- } else {
- ASSERT(kind() == Code::LOAD_IC);
- // ----------- S t a t e -------------
- // -- a2 : name
- // -- ra : return address
- // -- a0 : receiver
- // -- sp[0] : receiver
- // -----------------------------------
- receiver = a0;
}
StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3, t0,
&miss);
=======================================
--- /trunk/src/mips/debug-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/debug-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -207,9 +207,7 @@
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-arm.cc).
- Register receiver = KeyedLoadIC::ReceiverRegister();
- Register name = KeyedLoadIC::NameRegister();
- Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
+ GenerateLoadICDebugBreak(masm);
}
=======================================
--- /trunk/src/mips/full-codegen-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/full-codegen-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -141,7 +141,7 @@
__ Branch(&ok, ne, a2, Operand(at));
__ lw(a2, GlobalObjectOperand());
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
__ sw(a2, MemOperand(sp, receiver_offset));
@@ -1871,9 +1871,9 @@
break;
case NAMED_PROPERTY:
if (expr->is_compound()) {
- // We need the receiver both on the stack and in the accumulator.
- VisitForAccumulatorValue(property->obj());
- __ push(result_register());
+ // We need the receiver both on the stack and in the register.
+ VisitForStackValue(property->obj());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
} else {
VisitForStackValue(property->obj());
}
@@ -1882,9 +1882,9 @@
// We need the key and receiver on both the stack and in v0 and a1.
if (expr->is_compound()) {
VisitForStackValue(property->obj());
- VisitForAccumulatorValue(property->key());
- __ lw(a1, MemOperand(sp, 0));
- __ push(v0);
+ VisitForStackValue(property->key());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 *
kPointerSize));
+ __ lw(LoadIC::NameRegister(), MemOperand(sp, 0));
} else {
VisitForStackValue(property->obj());
VisitForStackValue(property->key());
@@ -2022,6 +2022,9 @@
Label l_catch, l_try, l_suspend, l_continuation, l_resume;
Label l_next, l_call;
+ Register load_receiver = LoadIC::ReceiverRegister();
+ Register load_name = LoadIC::NameRegister();
+
// Initial send value is undefined.
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Branch(&l_next);
@@ -2030,9 +2033,9 @@
__ bind(&l_catch);
__ mov(a0, v0);
handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
- __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
- __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
- __ Push(a2, a3, a0); // "throw", iter,
except
+ __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
+ __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
+ __ Push(load_name, a3, a0); // "throw", iter,
except
__ jmp(&l_call);
// try { received = %yield result }
@@ -2068,19 +2071,15 @@
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
- Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
- Register keyedload_name = KeyedLoadIC::NameRegister();
- ASSERT(keyedload_receiver.is(a1));
- ASSERT(keyedload_name.is(a0));
- __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
- __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
- __ Push(a2, a3, a0); // "next", iter,
received
+ __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next"
+ __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
+ __ Push(load_name, a3, a0); // "next", iter,
received
// result = receiver[f](arg);
__ bind(&l_call);
- __ lw(keyedload_receiver, MemOperand(sp, kPointerSize));
- __ lw(keyedload_name, MemOperand(sp, 2 * kPointerSize));
+ __ lw(load_receiver, MemOperand(sp, kPointerSize));
+ __ lw(load_name, MemOperand(sp, 2 * kPointerSize));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0);
@@ -2093,16 +2092,12 @@
__ Drop(1); // The function is still on the stack; drop it.
// if (!result.done) goto l_try;
- Register load_receiver = LoadIC::ReceiverRegister();
- Register load_name = LoadIC::NameRegister();
- ASSERT(load_receiver.is(a0));
- ASSERT(load_name.is(a2));
+ __ Move(load_receiver, v0);
- __ mov(load_receiver, v0);
- __ push(v0); // save result
+ __ push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
CallLoadIC(NOT_CONTEXTUAL); //
v0=result.done
- __ mov(load_receiver, v0);
+ __ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ Branch(&l_try, eq, v0, Operand(zero_reg));
@@ -2272,7 +2267,6 @@
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
- __ mov(LoadIC::ReceiverRegister(), result_register());
__ li(LoadIC::NameRegister(), Operand(key->value()));
// Call load IC. It has register arguments receiver and property.
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2281,7 +2275,6 @@
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
- __ mov(a0, result_register());
// Call keyed load IC. It has register arguments receiver and key.
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, prop->PropertyFeedbackId());
@@ -2580,16 +2573,15 @@
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
- ASSERT(a0.is(LoadIC::ReceiverRegister()));
+ __ Move(LoadIC::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0);
} else {
VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key());
- ASSERT(a0.is(KeyedLoadIC::NameRegister()));
- ASSERT(a1.is(KeyedLoadIC::ReceiverRegister()));
- __ pop(KeyedLoadIC::ReceiverRegister());
+ __ Move(LoadIC::NameRegister(), v0);
+ __ pop(LoadIC::ReceiverRegister());
EmitKeyedPropertyLoad(expr);
context()->Plug(v0);
}
@@ -2623,7 +2615,7 @@
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
- __ lw(v0, MemOperand(sp, 0));
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
@@ -2641,13 +2633,13 @@
Expression* key) {
// Load the key.
VisitForAccumulatorValue(key);
- ASSERT(a0.is(KeyedLoadIC::NameRegister()));
Expression* callee = expr->expression();
// Load the function from the receiver.
ASSERT(callee->IsProperty());
- __ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0));
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
+ __ Move(LoadIC::NameRegister(), v0);
EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@@ -4093,12 +4085,12 @@
if (expr->is_jsruntime()) {
// Push the builtins object as the receiver.
- __ lw(a0, GlobalObjectOperand());
- __ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset));
- __ push(a0);
+ Register receiver = LoadIC::ReceiverRegister();
+ __ lw(receiver, GlobalObjectOperand());
+ __ lw(receiver, FieldMemOperand(receiver,
GlobalObject::kBuiltinsOffset));
+ __ push(receiver);
// Load the function from the receiver.
- ASSERT(a0.is(LoadIC::ReceiverRegister()));
__ li(LoadIC::NameRegister(), Operand(expr->name()));
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4276,16 +4268,15 @@
__ push(at);
}
if (assign_type == NAMED_PROPERTY) {
- // Put the object both on the stack and in the accumulator.
- VisitForAccumulatorValue(prop->obj());
- __ push(v0);
+ // Put the object both on the stack and in the register.
+ VisitForStackValue(prop->obj());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(prop);
} else {
VisitForStackValue(prop->obj());
- VisitForAccumulatorValue(prop->key());
- ASSERT(a1.is(KeyedLoadIC::ReceiverRegister()));
- __ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0));
- __ push(v0);
+ VisitForStackValue(prop->key());
+ __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
+ __ lw(LoadIC::NameRegister(), MemOperand(sp, 0));
EmitKeyedPropertyLoad(prop);
}
}
=======================================
--- /trunk/src/mips/ic-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/ic-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -317,18 +317,16 @@
void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- a2 : name
- // -- ra : return address
- // -- a0 : receiver
- // -----------------------------------
- ASSERT(a0.is(ReceiverRegister()));
- ASSERT(a2.is(NameRegister()));
+ // The return address is in lr.
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ ASSERT(receiver.is(a1));
+ ASSERT(name.is(a2));
// Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
masm->isolate()->stub_cache()->GenerateProbe(
- masm, flags, a0, a2, a3, t0, t1, t2);
+ masm, flags, receiver, name, a3, t0, t1, t2);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
@@ -339,17 +337,17 @@
// ----------- S t a t e -------------
// -- a2 : name
// -- lr : return address
- // -- a0 : receiver
+ // -- a1 : receiver
// -----------------------------------
- ASSERT(a0.is(ReceiverRegister()));
+ ASSERT(a1.is(ReceiverRegister()));
ASSERT(a2.is(NameRegister()));
Label miss, slow;
- GenerateNameDictionaryReceiverCheck(masm, a0, a1, a3, t0, &miss);
+ GenerateNameDictionaryReceiverCheck(masm, a1, a0, a3, t0, &miss);
- // a1: elements
- GenerateDictionaryLoad(masm, &slow, a1, a2, v0, a3, t0);
+ // a0: elements
+ GenerateDictionaryLoad(masm, &slow, a0, a2, v0, a3, t0);
__ Ret();
// Dictionary load failed, go slow (but don't miss).
@@ -367,7 +365,7 @@
void LoadIC::GenerateMiss(MacroAssembler* masm) {
- // The return address is on the stack.
+ // The return address is in ra.
Isolate* isolate = masm->isolate();
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0);
@@ -382,7 +380,7 @@
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
- // The return address is on the stack.
+ // The return address is in ra.
__ mov(LoadIC_TempRegister(), ReceiverRegister());
__ Push(LoadIC_TempRegister(), NameRegister());
@@ -482,27 +480,27 @@
void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- lr : return address
- // -- a0 : key
- // -- a1 : receiver
- // -----------------------------------
- ASSERT(a1.is(ReceiverRegister()));
- ASSERT(a0.is(NameRegister()));
+ // The return address is in ra.
+ Register receiver = ReceiverRegister();
+ Register key = NameRegister();
+ ASSERT(receiver.is(a1));
+ ASSERT(key.is(a2));
+
Label slow, notin;
MemOperand mapped_location =
- GenerateMappedArgumentsLookup(masm, a1, a0, a2, a3, t0, ¬in,
&slow);
+ GenerateMappedArgumentsLookup(
+ masm, receiver, key, a0, a3, t0, ¬in, &slow);
__ Ret(USE_DELAY_SLOT);
__ lw(v0, mapped_location);
__ bind(¬in);
- // The unmapped lookup expects that the parameter map is in a2.
+ // The unmapped lookup expects that the parameter map is in a0.
MemOperand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, a0, a2, a3, &slow);
- __ lw(a2, unmapped_location);
+ GenerateUnmappedArgumentsLookup(masm, key, a0, a3, &slow);
+ __ lw(a0, unmapped_location);
__ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
- __ Branch(&slow, eq, a2, Operand(a3));
+ __ Branch(&slow, eq, a0, Operand(a3));
__ Ret(USE_DELAY_SLOT);
- __ mov(v0, a2);
+ __ mov(v0, a0);
__ bind(&slow);
GenerateMiss(masm);
}
@@ -544,7 +542,7 @@
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
- // The return address is on the stack.
+ // The return address is in ra.
Isolate* isolate = masm->isolate();
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0);
@@ -560,14 +558,12 @@
// IC register specifications
-const Register LoadIC::ReceiverRegister() { return a0; }
+const Register LoadIC::ReceiverRegister() { return a1; }
const Register LoadIC::NameRegister() { return a2; }
-const Register KeyedLoadIC::ReceiverRegister() { return a1; }
-const Register KeyedLoadIC::NameRegister() { return a0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
- // The return address is on the stack.
+ // The return address is in ra.
__ Push(ReceiverRegister(), NameRegister());
@@ -576,17 +572,13 @@
void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- ra : return address
- // -- a0 : key
- // -- a1 : receiver
- // -----------------------------------
+ // The return address is in ra.
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
Register key = NameRegister();
Register receiver = ReceiverRegister();
- ASSERT(key.is(a0));
+ ASSERT(key.is(a2));
ASSERT(receiver.is(a1));
Isolate* isolate = masm->isolate();
@@ -598,15 +590,14 @@
// where a numeric string is converted to a smi.
GenerateKeyedLoadReceiverCheck(
- masm, receiver, a2, a3, Map::kHasIndexedInterceptor, &slow);
+ masm, receiver, a0, a3, Map::kHasIndexedInterceptor, &slow);
// Check the receiver's map to see if it has fast elements.
- __ CheckFastElements(a2, a3, &check_number_dictionary);
+ __ CheckFastElements(a0, a3, &check_number_dictionary);
GenerateFastArrayLoad(
- masm, receiver, key, t0, a3, a2, v0, NULL, &slow);
-
- __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1,
a2, a3);
+ masm, receiver, key, a0, a3, t0, v0, NULL, &slow);
+ __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1,
t0, a3);
__ Ret();
__ bind(&check_number_dictionary);
@@ -614,42 +605,41 @@
__ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset));
// Check whether the elements is a number dictionary.
- // a0: key
// a3: elements map
// t0: elements
__ LoadRoot(at, Heap::kHashTableMapRootIndex);
__ Branch(&slow, ne, a3, Operand(at));
- __ sra(a2, a0, kSmiTagSize);
- __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
+ __ sra(a0, key, kSmiTagSize);
+ __ LoadFromNumberDictionary(&slow, t0, key, v0, a0, a3, t1);
__ Ret();
- // Slow case, key and receiver still in a0 and a1.
+ // Slow case, key and receiver still in a2 and a1.
__ bind(&slow);
__ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
1,
- a2,
+ t0,
a3);
GenerateRuntimeGetProperty(masm);
__ bind(&check_name);
- GenerateKeyNameCheck(masm, key, a2, a3, &index_name, &slow);
+ GenerateKeyNameCheck(masm, key, a0, a3, &index_name, &slow);
GenerateKeyedLoadReceiverCheck(
- masm, receiver, a2, a3, Map::kHasNamedInterceptor, &slow);
+ masm, receiver, a0, a3, Map::kHasNamedInterceptor, &slow);
// If the receiver is a fast-case object, check the keyed lookup
// cache. Otherwise probe the dictionary.
- __ lw(a3, FieldMemOperand(a1, JSObject::kPropertiesOffset));
+ __ lw(a3, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
__ lw(t0, FieldMemOperand(a3, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kHashTableMapRootIndex);
__ Branch(&probe_dictionary, eq, t0, Operand(at));
// Load the map of the receiver, compute the keyed lookup cache hash
// based on 32 bits of the map pointer and the name hash.
- __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset));
- __ sra(a3, a2, KeyedLookupCache::kMapHashShift);
- __ lw(t0, FieldMemOperand(a0, Name::kHashFieldOffset));
+ __ lw(a0, FieldMemOperand(receiver, HeapObject::kMapOffset));
+ __ sra(a3, a0, KeyedLookupCache::kMapHashShift);
+ __ lw(t0, FieldMemOperand(key, Name::kHashFieldOffset));
__ sra(at, t0, Name::kHashShift);
__ xor_(a3, a3, at);
int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
@@ -669,21 +659,19 @@
for (int i = 0; i < kEntriesPerBucket - 1; i++) {
Label try_next_entry;
__ lw(t1, MemOperand(t0, kPointerSize * i * 2));
- __ Branch(&try_next_entry, ne, a2, Operand(t1));
+ __ Branch(&try_next_entry, ne, a0, Operand(t1));
__ lw(t1, MemOperand(t0, kPointerSize * (i * 2 + 1)));
- __ Branch(&hit_on_nth_entry[i], eq, a0, Operand(t1));
+ __ Branch(&hit_on_nth_entry[i], eq, key, Operand(t1));
__ bind(&try_next_entry);
}
__ lw(t1, MemOperand(t0, kPointerSize * (kEntriesPerBucket - 1) * 2));
- __ Branch(&slow, ne, a2, Operand(t1));
+ __ Branch(&slow, ne, a0, Operand(t1));
__ lw(t1, MemOperand(t0, kPointerSize * ((kEntriesPerBucket - 1) * 2 +
1)));
- __ Branch(&slow, ne, a0, Operand(t1));
+ __ Branch(&slow, ne, key, Operand(t1));
// Get field offset.
- // a0 : key
- // a1 : receiver
- // a2 : receiver's map
+ // a0 : receiver's map
// a3 : lookup cache index
ExternalReference cache_field_offsets =
ExternalReference::keyed_lookup_cache_field_offsets(isolate);
@@ -695,7 +683,7 @@
__ sll(at, a3, kPointerSizeLog2);
__ addu(at, t0, at);
__ lw(t1, MemOperand(at, kPointerSize * i));
- __ lbu(t2, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
+ __ lbu(t2, FieldMemOperand(a0, Map::kInObjectPropertiesOffset));
__ Subu(t1, t1, t2);
__ Branch(&property_array_property, ge, t1, Operand(zero_reg));
if (i != 0) {
@@ -705,28 +693,28 @@
// Load in-object property.
__ bind(&load_in_object_property);
- __ lbu(t2, FieldMemOperand(a2, Map::kInstanceSizeOffset));
+ __ lbu(t2, FieldMemOperand(a0, Map::kInstanceSizeOffset));
__ addu(t2, t2, t1); // Index from start of object.
- __ Subu(a1, a1, Operand(kHeapObjectTag)); // Remove the heap tag.
+ __ Subu(receiver, receiver, Operand(kHeapObjectTag)); // Remove the
heap tag.
__ sll(at, t2, kPointerSizeLog2);
- __ addu(at, a1, at);
+ __ addu(at, receiver, at);
__ lw(v0, MemOperand(at));
__
IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
1,
- a2,
+ t0,
a3);
__ Ret();
// Load property array property.
__ bind(&property_array_property);
- __ lw(a1, FieldMemOperand(a1, JSObject::kPropertiesOffset));
- __ Addu(a1, a1, FixedArray::kHeaderSize - kHeapObjectTag);
- __ sll(t0, t1, kPointerSizeLog2);
- __ Addu(t0, t0, a1);
- __ lw(v0, MemOperand(t0));
+ __ lw(receiver, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+ __ Addu(receiver, receiver, FixedArray::kHeaderSize - kHeapObjectTag);
+ __ sll(v0, t1, kPointerSizeLog2);
+ __ Addu(v0, v0, receiver);
+ __ lw(v0, MemOperand(v0));
__
IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
1,
- a2,
+ t0,
a3);
__ Ret();
@@ -734,17 +722,15 @@
// Do a quick inline probe of the receiver's dictionary, if it
// exists.
__ bind(&probe_dictionary);
- // a1: receiver
- // a0: key
// a3: elements
- __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset));
- __ lbu(a2, FieldMemOperand(a2, Map::kInstanceTypeOffset));
- GenerateGlobalInstanceTypeCheck(masm, a2, &slow);
+ __ lw(a0, FieldMemOperand(receiver, HeapObject::kMapOffset));
+ __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
+ GenerateGlobalInstanceTypeCheck(masm, a0, &slow);
// Load the property to v0.
- GenerateDictionaryLoad(masm, &slow, a3, a0, v0, a2, t0);
+ GenerateDictionaryLoad(masm, &slow, a3, key, v0, t1, t0);
__ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(),
1,
- a2,
+ t0,
a3);
__ Ret();
@@ -756,7 +742,7 @@
void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // Return address is on the stack.
+ // Return address is in ra.
Label miss;
Register receiver = ReceiverRegister();
@@ -1071,13 +1057,13 @@
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
- // Return address is on the stack.
+ // Return address is in ra.
Label slow;
Register receiver = ReceiverRegister();
Register key = NameRegister();
- Register scratch1 = a2;
- Register scratch2 = a3;
+ Register scratch1 = a3;
+ Register scratch2 = t0;
ASSERT(!scratch1.is(receiver) && !scratch1.is(key));
ASSERT(!scratch2.is(receiver) && !scratch2.is(key));
=======================================
--- /trunk/src/mips/lithium-codegen-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/lithium-codegen-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -152,7 +152,7 @@
__ Branch(&ok, ne, a2, Operand(at));
__ lw(a2, GlobalObjectOperand());
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
__ sw(a2, MemOperand(sp, receiver_offset));
@@ -3327,8 +3327,8 @@
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister()));
- ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister()));
+ ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
+ ASSERT(ToRegister(instr->key()).is(LoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3425,7 +3425,7 @@
__ lw(result,
ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
__ lw(result,
- FieldMemOperand(result, GlobalObject::kGlobalReceiverOffset));
+ FieldMemOperand(result, GlobalObject::kGlobalProxyOffset));
if (result.is(receiver)) {
__ bind(&result_in_receiver);
=======================================
--- /trunk/src/mips/lithium-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/lithium-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -2145,8 +2145,8 @@
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
- LOperand* object = UseFixed(instr->object(),
KeyedLoadIC::ReceiverRegister());
- LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister());
+ LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
+ LOperand* key = UseFixed(instr->key(), LoadIC::NameRegister());
LInstruction* result =
DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0);
=======================================
--- /trunk/src/mips/stub-cache-mips.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/mips/stub-cache-mips.cc Fri Jul 4 16:46:28 2014 UTC
@@ -1195,8 +1195,7 @@
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ lw(receiver,
- FieldMemOperand(
- receiver, JSGlobalObject::kGlobalReceiverOffset));
+ FieldMemOperand(receiver,
JSGlobalObject::kGlobalProxyOffset));
}
__ Push(receiver, value());
ParameterCount actual(1);
@@ -1256,16 +1255,16 @@
// receiver, name, scratch1, scratch2, scratch3, scratch4.
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
- static Register registers[] = { receiver, name, a3, a1, t0, t1 };
+ static Register registers[] = { receiver, name, a3, a0, t0, t1 };
return registers;
}
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
- Register receiver = KeyedLoadIC::ReceiverRegister();
- Register name = KeyedLoadIC::NameRegister();
- static Register registers[] = { receiver, name, a2, a3, t0, t1 };
+ Register receiver = LoadIC::ReceiverRegister();
+ Register name = LoadIC::NameRegister();
+ static Register registers[] = { receiver, name, a3, a0, t0, t1 };
return registers;
}
@@ -1310,8 +1309,7 @@
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ lw(receiver,
- FieldMemOperand(
- receiver, JSGlobalObject::kGlobalReceiverOffset));
+ FieldMemOperand(receiver,
JSGlobalObject::kGlobalProxyOffset));
}
__ push(receiver);
ParameterCount actual(0);
@@ -1466,45 +1464,30 @@
void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- ra : return address
- // -- a0 : key
- // -- a1 : receiver
- // -----------------------------------
- ASSERT(a1.is(KeyedLoadIC::ReceiverRegister()));
- ASSERT(a0.is(KeyedLoadIC::NameRegister()));
+ // The return address is in ra.
Label slow, miss;
- Register key = a0;
- Register receiver = a1;
+ Register key = LoadIC::NameRegister();
+ Register receiver = LoadIC::ReceiverRegister();
+ ASSERT(receiver.is(a1));
+ ASSERT(key.is(a2));
- __ JumpIfNotSmi(key, &miss);
+ __ UntagAndJumpIfNotSmi(t2, key, &miss);
__ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ sra(a2, a0, kSmiTagSize);
- __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
+ __ LoadFromNumberDictionary(&slow, t0, key, v0, t2, a3, t1);
__ Ret();
- // Slow case, key and receiver still in a0 and a1.
+ // Slow case, key and receiver still unmodified.
__ bind(&slow);
__ IncrementCounter(
masm->isolate()->counters()->keyed_load_external_array_slow(),
1, a2, a3);
- // Entry registers are intact.
- // ---------- S t a t e --------------
- // -- ra : return address
- // -- a0 : key
- // -- a1 : receiver
- // -----------------------------------
+
TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
// Miss case, call the runtime.
__ bind(&miss);
- // ---------- S t a t e --------------
- // -- ra : return address
- // -- a0 : key
- // -- a1 : receiver
- // -----------------------------------
TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
}
=======================================
--- /trunk/src/objects.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/objects.cc Fri Jul 4 16:46:28 2014 UTC
@@ -2062,14 +2062,13 @@
}
-bool Map::InstancesNeedRewriting(Map* target,
- int target_number_of_fields,
- int target_inobject,
- int target_unused) {
+bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
+ int target_inobject, int target_unused,
+ int* old_number_of_fields) {
// If fields were added (or removed), rewrite the instance.
- int number_of_fields = NumberOfFields();
- ASSERT(target_number_of_fields >= number_of_fields);
- if (target_number_of_fields != number_of_fields) return true;
+ *old_number_of_fields = NumberOfFields();
+ ASSERT(target_number_of_fields >= *old_number_of_fields);
+ if (target_number_of_fields != *old_number_of_fields) return true;
// If smi descriptors were replaced by double descriptors, rewrite.
DescriptorArray* old_desc = instance_descriptors();
@@ -2147,14 +2146,15 @@
void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map>
new_map) {
Isolate* isolate = object->GetIsolate();
Handle<Map> old_map(object->map());
+ int old_number_of_fields;
int number_of_fields = new_map->NumberOfFields();
int inobject = new_map->inobject_properties();
int unused = new_map->unused_property_fields();
// Nothing to do if no functions were converted to fields and no smis
were
// converted to doubles.
- if (!old_map->InstancesNeedRewriting(
- *new_map, number_of_fields, inobject, unused)) {
+ if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields,
inobject,
+ unused, &old_number_of_fields)) {
object->synchronized_set_map(*new_map);
return;
}
@@ -2163,7 +2163,9 @@
int external = total_size - inobject;
if ((old_map->unused_property_fields() == 0) &&
+ (number_of_fields != old_number_of_fields) &&
(new_map->GetBackPointer() == *old_map)) {
+ ASSERT(number_of_fields == old_number_of_fields + 1);
// This migration is a transition from a map that has run out out
property
// space. Therefore it could be done by extending the backing store.
Handle<FixedArray> old_storage = handle(object->properties(), isolate);
=======================================
--- /trunk/src/objects.h Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/objects.h Fri Jul 4 16:46:28 2014 UTC
@@ -6285,10 +6285,9 @@
int NumberOfFields();
// TODO(ishell): candidate with JSObject::MigrateToMap().
- bool InstancesNeedRewriting(Map* target,
- int target_number_of_fields,
- int target_inobject,
- int target_unused);
+ bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
+ int target_inobject, int target_unused,
+ int* old_number_of_fields);
// TODO(ishell): moveit!
static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
MUST_USE_RESULT static Handle<HeapType> GeneralizeFieldType(
=======================================
--- /trunk/src/version.cc Fri Jul 4 16:39:51 2014 UTC
+++ /trunk/src/version.cc Fri Jul 4 16:46:28 2014 UTC
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 28
#define BUILD_NUMBER 13
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 1
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.