Version 3.19.17.
Rollback to source of 3.19.15 plus bug fix for chromium:249866
R=jkummerow@chromium.org
Review URL: https://chromiumcodereview.appspot.com/17162002
git-svn-id: http://v8.googlecode.com/svn/trunk@15175 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 9b1d01c..a7e0b28 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -8005,55 +8005,4 @@
}
-v8::Handle<v8::Value> InvokeAccessorGetter(
- v8::Local<v8::String> property,
- const v8::AccessorInfo& info,
- v8::AccessorGetter getter) {
- Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
- Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
- getter));
- // Leaving JavaScript.
- VMState<EXTERNAL> state(isolate);
- ExternalCallbackScope call_scope(isolate, getter_address);
- return getter(property, info);
-}
-
-
-void InvokeAccessorGetterCallback(
- v8::Local<v8::String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info,
- v8::AccessorGetterCallback getter) {
- // Leaving JavaScript.
- Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
- Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
- getter));
- VMState<EXTERNAL> state(isolate);
- ExternalCallbackScope call_scope(isolate, getter_address);
- return getter(property, info);
-}
-
-
-v8::Handle<v8::Value> InvokeInvocationCallback(
- const v8::Arguments& args,
- v8::InvocationCallback callback) {
- Isolate* isolate = reinterpret_cast<Isolate*>(args.GetIsolate());
- Address callback_address =
- reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
- VMState<EXTERNAL> state(isolate);
- ExternalCallbackScope call_scope(isolate, callback_address);
- return callback(args);
-}
-
-
-void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
- v8::FunctionCallback callback) {
- Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
- Address callback_address =
- reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
- VMState<EXTERNAL> state(isolate);
- ExternalCallbackScope call_scope(isolate, callback_address);
- return callback(info);
-}
-
-
} } // namespace v8::internal
diff --git a/src/api.h b/src/api.h
index 50d4b38..3d1c69c 100644
--- a/src/api.h
+++ b/src/api.h
@@ -680,24 +680,6 @@
}
-// Interceptor functions called from generated inline caches to notify
-// CPU profiler that external callbacks are invoked.
-v8::Handle<v8::Value> InvokeAccessorGetter(
- v8::Local<v8::String> property,
- const v8::AccessorInfo& info,
- v8::AccessorGetter getter);
-
-
-void InvokeAccessorGetterCallback(
- v8::Local<v8::String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info,
- v8::AccessorGetterCallback getter);
-
-v8::Handle<v8::Value> InvokeInvocationCallback(const v8::Arguments& args,
- v8::InvocationCallback callback);
-void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
- v8::FunctionCallback callback);
-
class Testing {
public:
static v8::Testing::StressType stress_type() { return stress_type_; }
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index e75e7f7..ee6eb97 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -6482,6 +6482,13 @@
void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
+ ExternalReference function) {
+ __ mov(r2, Operand(function));
+ GenerateCall(masm, r2);
+}
+
+
+void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
Register target) {
intptr_t code =
reinterpret_cast<intptr_t>(GetCode(masm->isolate()).location());
@@ -7055,10 +7062,10 @@
void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : element value to store
+ // -- r1 : array literal
+ // -- r2 : map of array literal
// -- r3 : element index as smi
- // -- sp[0] : array literal index in function as smi
- // -- sp[4] : array literal
- // clobbers r1, r2, r4
+ // -- r4 : array literal index in function as smi
// -----------------------------------
Label element_done;
@@ -7067,11 +7074,6 @@
Label slow_elements;
Label fast_elements;
- // Get array literal index, array literal and its map.
- __ ldr(r4, MemOperand(sp, 0 * kPointerSize));
- __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
- __ ldr(r2, FieldMemOperand(r1, JSObject::kMapOffset));
-
__ CheckFastElements(r2, r5, &double_elements);
// FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS
__ JumpIfSmi(r0, &smi_element);
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index 1f663f5..863848c 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -585,6 +585,7 @@
public:
DirectCEntryStub() {}
void Generate(MacroAssembler* masm);
+ void GenerateCall(MacroAssembler* masm, ExternalReference function);
void GenerateCall(MacroAssembler* masm, Register target);
private:
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 77d5524..468fa77 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -361,7 +361,7 @@
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ b(pl, &ok);
@@ -404,7 +404,7 @@
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -1836,14 +1836,13 @@
if (!result_saved) {
__ push(r0);
- __ Push(Smi::FromInt(expr->literal_index()));
result_saved = true;
}
VisitForAccumulatorValue(subexpr);
if (IsFastObjectElementsKind(constant_elements_kind)) {
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
- __ ldr(r6, MemOperand(sp, kPointerSize)); // Copy of array literal.
+ __ ldr(r6, MemOperand(sp)); // Copy of array literal.
__ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset));
__ str(result_register(), FieldMemOperand(r1, offset));
// Update the write barrier for the array store.
@@ -1851,7 +1850,10 @@
kLRHasBeenSaved, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
} else {
+ __ ldr(r1, MemOperand(sp)); // Copy of array literal.
+ __ ldr(r2, FieldMemOperand(r1, JSObject::kMapOffset));
__ mov(r3, Operand(Smi::FromInt(i)));
+ __ mov(r4, Operand(Smi::FromInt(expr->literal_index())));
StoreArrayLiteralElementStub stub;
__ CallStub(&stub);
}
@@ -1860,7 +1862,6 @@
}
if (result_saved) {
- __ pop(); // literal index
context()->PlugTOS();
} else {
context()->Plug(r0);
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 3d421c1..87865b2 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -1581,8 +1581,8 @@
}
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
- StrictModeFlag strict_mode) {
+void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
+ StrictModeFlag strict_mode) {
// ----------- S t a t e -------------
// -- r0 : value
// -- r1 : receiver
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index e468b11..fbb9c6e 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -929,7 +929,7 @@
BailoutId ast_id = hydrogen_env->ast_id();
ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
- int value_count = hydrogen_env->length() - hydrogen_env->specials_count();
+ int value_count = hydrogen_env->length();
LEnvironment* result = new(zone()) LEnvironment(
hydrogen_env->closure(),
hydrogen_env->frame_type(),
@@ -940,15 +940,13 @@
outer,
hydrogen_env->entry(),
zone());
- bool needs_arguments_object_materialization = false;
int argument_index = *argument_index_accumulator;
- for (int i = 0; i < hydrogen_env->length(); ++i) {
+ for (int i = 0; i < value_count; ++i) {
if (hydrogen_env->is_special_index(i)) continue;
HValue* value = hydrogen_env->values()->at(i);
LOperand* op = NULL;
if (value->IsArgumentsObject()) {
- needs_arguments_object_materialization = true;
op = NULL;
} else if (value->IsPushArgument()) {
op = new(zone()) LArgument(argument_index++);
@@ -960,21 +958,6 @@
value->CheckFlag(HInstruction::kUint32));
}
- if (needs_arguments_object_materialization) {
- HArgumentsObject* arguments = hydrogen_env->entry() == NULL
- ? graph()->GetArgumentsObject()
- : hydrogen_env->entry()->arguments_object();
- ASSERT(arguments->IsLinked());
- for (int i = 1; i < arguments->arguments_count(); ++i) {
- HValue* value = arguments->arguments_values()->at(i);
- ASSERT(!value->IsArgumentsObject() && !value->IsPushArgument());
- LOperand* op = UseAny(value);
- result->AddValue(op,
- value->representation(),
- value->CheckFlag(HInstruction::kUint32));
- }
- }
-
if (hydrogen_env->frame_type() == JS_FUNCTION) {
*argument_index_accumulator = argument_index;
}
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 253c63d..5acf360 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -580,15 +580,27 @@
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* pushed_arguments_index,
+ int* pushed_arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
- int translation_size = environment->translation_size();
+ int translation_size = environment->values()->length();
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *pushed_arguments_index = -environment->parameter_count();
+ *pushed_arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ pushed_arguments_index,
+ pushed_arguments_count);
bool has_closure_id = !info()->closure().is_null() &&
!info()->closure().is_identical_to(environment->closure());
int closure_id = has_closure_id
@@ -620,6 +632,23 @@
break;
}
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and another stack area to be used for materialization,
+ // otherwise actual argument values are unknown for inlined frames.
+ bool arguments_known = true;
+ int arguments_index = *pushed_arguments_index;
+ int arguments_count = *pushed_arguments_count;
+ if (environment->entry() != NULL) {
+ arguments_known = environment->entry()->arguments_pushed();
+ arguments_index = arguments_index < 0
+ ? GetStackSlotCount() : arguments_index + arguments_count;
+ arguments_count = environment->entry()->arguments_count() + 1;
+ if (environment->entry()->arguments_pushed()) {
+ *pushed_arguments_index = arguments_index;
+ *pushed_arguments_count = arguments_count;
+ }
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -631,7 +660,10 @@
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -640,36 +672,20 @@
translation,
environment->spilled_double_registers()[value->index()],
false,
- false);
+ false,
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
- // TODO(mstarzinger): Introduce marker operands to indicate that this value
- // is not present and must be reconstructed from the deoptimizer. Currently
- // this is only used for the arguments object.
- if (value == NULL) {
- int arguments_count = environment->values()->length() - translation_size;
- translation->BeginArgumentsObject(arguments_count);
- for (int i = 0; i < arguments_count; ++i) {
- LOperand* value = environment->values()->at(translation_size + i);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsRegister() ||
- environment->spilled_registers()[value->index()] == NULL);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsDoubleRegister() ||
- environment->spilled_double_registers()[value->index()] == NULL);
- AddToTranslation(translation,
- value,
- environment->HasTaggedValueAt(translation_size + i),
- environment->HasUint32ValueAt(translation_size + i));
- }
- continue;
- }
-
AddToTranslation(translation,
value,
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
@@ -677,8 +693,17 @@
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32) {
- if (op->IsStackSlot()) {
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count) {
+ if (op == NULL) {
+ // TODO(twuerthinger): Introduce marker operands to indicate that this value
+ // is not present and must be reconstructed from the deoptimizer. Currently
+ // this is only used for the arguments object.
+ translation->StoreArgumentsObject(
+ arguments_known, arguments_index, arguments_count);
+ } else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
} else if (is_uint32) {
@@ -785,6 +810,8 @@
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
@@ -792,7 +819,7 @@
}
}
Translation translation(&translations_, frame_count, jsframe_count, zone());
- WriteTranslation(environment, &translation);
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index aeba5ea..cecf152 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -171,7 +171,10 @@
int additional_offset);
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) void Do##type(L##type* node);
@@ -290,7 +293,10 @@
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32);
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count);
void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 81a2d37..4b6eac2 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -2244,9 +2244,6 @@
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
- Address function_address,
- ExternalReference thunk_ref,
- Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset) {
@@ -2277,31 +2274,11 @@
PopSafepointRegisters();
}
- ASSERT(!thunk_last_arg.is(r3));
- Label profiler_disabled;
- Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- mov(r3, Operand(reinterpret_cast<int32_t>(is_profiling_flag)));
- ldrb(r3, MemOperand(r3, 0));
- cmp(r3, Operand(0));
- b(eq, &profiler_disabled);
-
- // Additional parameter is the address of the actual callback.
- mov(thunk_last_arg, Operand(reinterpret_cast<int32_t>(function_address)));
- mov(r3, Operand(thunk_ref));
- jmp(&end_profiler_check);
-
- bind(&profiler_disabled);
- mov(r3, Operand(function));
- bind(&end_profiler_check);
-
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
DirectCEntryStub stub;
- stub.GenerateCall(this, r3);
+ stub.GenerateCall(this, function);
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 8d3626d..11d3066 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1085,9 +1085,6 @@
// - space to be unwound on exit (includes the call JS arguments space and
// the additional space allocated for the fast call).
void CallApiFunctionAndReturn(ExternalReference function,
- Address function_address,
- ExternalReference thunk_ref,
- Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp);
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index a29d461..c9db167 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -830,10 +830,7 @@
Isolate* isolate = Isolate::Current();
Redirection* current = isolate->simulator_redirection();
for (; current != NULL; current = current->next_) {
- if (current->external_function_ == external_function) {
- ASSERT_EQ(current->type(), type);
- return current;
- }
+ if (current->external_function_ == external_function) return current;
}
return new Redirection(external_function, type);
}
@@ -1632,19 +1629,12 @@
// (refer to InvocationCallback in v8.h).
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
- int32_t arg0, int32_t arg1);
-typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback.
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
int32_t arg1);
typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
int32_t arg1);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
- int32_t arg0, int32_t arg1, int32_t arg2);
-typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
- int32_t arg0, int32_t arg1, int32_t arg2);
// Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime.
@@ -1809,31 +1799,6 @@
target(arg0);
}
} else if (
- redirection->type() == ExternalReference::PROFILING_API_CALL ||
- redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
- if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
- PrintF("Call to host function at %p args %08x %08x",
- reinterpret_cast<void*>(external), arg0, arg1);
- if (!stack_aligned) {
- PrintF(" with unaligned stack %08x\n", get_register(sp));
- }
- PrintF("\n");
- }
- CHECK(stack_aligned);
- if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
- SimulatorRuntimeProfilingApiCall target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
- v8::Handle<v8::Value> result = target(arg0, arg1);
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }
- set_register(r0, reinterpret_cast<int32_t>(*result));
- } else {
- SimulatorRuntimeProfilingApiCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
- target(arg0, arg1);
- }
- } else if (
redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
@@ -1858,32 +1823,6 @@
reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
target(arg0, arg1);
}
- } else if (
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
- if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
- PrintF("Call to host function at %p args %08x %08x %08x",
- reinterpret_cast<void*>(external), arg0, arg1, arg2);
- if (!stack_aligned) {
- PrintF(" with unaligned stack %08x\n", get_register(sp));
- }
- PrintF("\n");
- }
- CHECK(stack_aligned);
- if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
- SimulatorRuntimeProfilingGetterCall target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
- v8::Handle<v8::Value> result = target(arg0, arg1, arg2);
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }
- set_register(r0, reinterpret_cast<int32_t>(*result));
- } else {
- SimulatorRuntimeProfilingGetterCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(
- external);
- target(arg0, arg1, arg2);
- }
} else {
// builtin call.
ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
@@ -1891,7 +1830,7 @@
reinterpret_cast<SimulatorRuntimeCall>(external);
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF(
- "Call to host function at %p "
+ "Call to host function at %p"
"args %08x, %08x, %08x, %08x, %08x, %08x",
FUNCTION_ADDR(target),
arg0,
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 737e449..1ccc106 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -512,13 +512,7 @@
Register storage_reg = name_reg;
- if (details.type() == CONSTANT_FUNCTION) {
- Handle<HeapObject> constant(
- HeapObject::cast(descriptors->GetValue(descriptor)));
- __ LoadHeapObject(scratch1, constant);
- __ cmp(value_reg, scratch1);
- __ b(ne, miss_restore_name);
- } else if (FLAG_track_fields && representation.IsSmi()) {
+ if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_restore_name);
} else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_restore_name);
@@ -547,8 +541,7 @@
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Perform map transition for the receiver if necessary.
- if (details.type() == FIELD &&
- object->map()->unused_property_fields() == 0) {
+ 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 properties array.
__ push(receiver_reg);
@@ -577,8 +570,6 @@
OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
- if (details.type() == CONSTANT_FUNCTION) return;
-
int index = transition->instance_descriptors()->GetFieldIndex(
transition->LastAdded());
@@ -965,22 +956,8 @@
ExternalReference ref = ExternalReference(&fun,
type,
masm->isolate());
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_API_CALL :
- ExternalReference::PROFILING_API_CALL_NEW;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
-
AllowExternalCallThatCantCauseGC scope(masm);
__ CallApiFunctionAndReturn(ref,
- function_address,
- thunk_ref,
- r1,
kStackUnwindSpace,
returns_handle,
kFastApiCallArguments + 1);
@@ -1477,28 +1454,14 @@
Address getter_address = v8::ToCData<Address>(callback->getter());
bool returns_handle =
!CallbackTable::ReturnsVoid(isolate(), getter_address);
-
ApiFunction fun(getter_address);
ExternalReference::Type type =
returns_handle ?
ExternalReference::DIRECT_GETTER_CALL :
ExternalReference::DIRECT_GETTER_CALL_NEW;
- ExternalReference ref = ExternalReference(&fun, type, isolate());
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
- ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_GETTER_CALL :
- ExternalReference::PROFILING_GETTER_CALL_NEW;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- isolate());
+ ExternalReference ref = ExternalReference(&fun, type, isolate());
__ CallApiFunctionAndReturn(ref,
- getter_address,
- thunk_ref,
- r2,
kStackUnwindSpace,
returns_handle,
5);
diff --git a/src/assembler.h b/src/assembler.h
index 95853e8..f66f8bf 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -647,35 +647,17 @@
// Handle<Value> f(v8::Arguments&)
DIRECT_API_CALL,
- // Call to invocation callback via InvokeInvocationCallback.
- // Handle<Value> f(v8::Arguments&, v8::InvocationCallback)
- PROFILING_API_CALL,
-
// Direct call to API function callback.
// void f(v8::Arguments&)
DIRECT_API_CALL_NEW,
- // Call to function callback via InvokeFunctionCallback.
- // void f(v8::Arguments&, v8::FunctionCallback)
- PROFILING_API_CALL_NEW,
-
// Direct call to accessor getter callback.
// Handle<value> f(Local<String> property, AccessorInfo& info)
DIRECT_GETTER_CALL,
- // Call to accessor getter callback via InvokeAccessorGetter.
- // Handle<value> f(Local<String> property, AccessorInfo& info,
- // AccessorGetter getter)
- PROFILING_GETTER_CALL,
-
// Direct call to accessor getter callback.
// void f(Local<String> property, AccessorInfo& info)
- DIRECT_GETTER_CALL_NEW,
-
- // Call to accessor getter callback via InvokeAccessorGetterCallback.
- // void f(Local<String> property, AccessorInfo& info,
- // AccessorGetterCallback callback)
- PROFILING_GETTER_CALL_NEW
+ DIRECT_GETTER_CALL_NEW
};
static void SetUp();
diff --git a/src/builtins.cc b/src/builtins.cc
index fd7dd8a..d97a477 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1496,12 +1496,12 @@
static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
- StoreIC::GenerateRuntimeSetProperty(masm, kNonStrictMode);
+ StoreIC::GenerateGlobalProxy(masm, kNonStrictMode);
}
static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
- StoreIC::GenerateRuntimeSetProperty(masm, kStrictMode);
+ StoreIC::GenerateGlobalProxy(masm, kStrictMode);
}
@@ -1510,16 +1510,6 @@
}
-static void Generate_StoreIC_Generic(MacroAssembler* masm) {
- StoreIC::GenerateRuntimeSetProperty(masm, kNonStrictMode);
-}
-
-
-static void Generate_StoreIC_Generic_Strict(MacroAssembler* masm) {
- StoreIC::GenerateRuntimeSetProperty(masm, kStrictMode);
-}
-
-
static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
}
diff --git a/src/builtins.h b/src/builtins.h
index df833df..c45fbfd 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -166,10 +166,6 @@
Code::kNoExtraICState) \
V(StoreIC_Megamorphic, STORE_IC, MEGAMORPHIC, \
Code::kNoExtraICState) \
- V(StoreIC_Generic, STORE_IC, GENERIC, \
- Code::kNoExtraICState) \
- V(StoreIC_Generic_Strict, STORE_IC, GENERIC, \
- kStrictMode) \
V(StoreIC_GlobalProxy, STORE_IC, GENERIC, \
Code::kNoExtraICState) \
V(StoreIC_Initialize_Strict, STORE_IC, UNINITIALIZED, \
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 11cd307..e1e25fb 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -144,7 +144,7 @@
set_current_block(next_block);
HConstant* undefined_constant = new(zone) HConstant(
- isolate()->factory()->undefined_value());
+ isolate()->factory()->undefined_value(), Representation::Tagged());
AddInstruction(undefined_constant);
graph()->set_undefined_constant(undefined_constant);
@@ -196,7 +196,8 @@
stack_pop_count->ClearFlag(HValue::kCanOverflow);
} else {
int count = descriptor_->hint_stack_parameter_count_;
- stack_pop_count = AddInstruction(new(zone) HConstant(count));
+ stack_pop_count = AddInstruction(new(zone)
+ HConstant(count, Representation::Integer32()));
}
}
@@ -390,11 +391,13 @@
HValue* boilerplate_size =
AddInstruction(new(zone) HInstanceSize(boilerplate));
HValue* size_in_words =
- AddInstruction(new(zone) HConstant(size >> kPointerSizeLog2));
+ AddInstruction(new(zone) HConstant(size >> kPointerSizeLog2,
+ Representation::Integer32()));
checker.IfCompare(boilerplate_size, size_in_words, Token::EQ);
checker.Then();
- HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size));
+ HValue* size_in_bytes =
+ AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
if (isolate()->heap()->ShouldGloballyPretenure()) {
flags = static_cast<HAllocate::Flags>(
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index 455c893..2f8479f 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -248,9 +248,6 @@
void SharedFunctionInfoMoveEvent(Address from, Address to);
INLINE(bool is_profiling() const) { return is_profiling_; }
- bool* is_profiling_address() {
- return &is_profiling_;
- }
private:
void StartProcessorIfNotStarted();
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index 298518d..5226364 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -150,19 +150,18 @@
static Persistent<Array> current_completions;
Isolate* isolate = read_line_editor.isolate_;
Locker lock(isolate);
- HandleScope scope;
- Handle<Array> completions;
if (state == 0) {
+ HandleScope scope;
Local<String> full_text = String::New(rl_line_buffer, rl_point);
- completions = Shell::GetCompletions(isolate, String::New(text), full_text);
- current_completions.Reset(isolate, completions);
+ Handle<Array> completions =
+ Shell::GetCompletions(isolate, String::New(text), full_text);
+ current_completions = Persistent<Array>::New(isolate, completions);
current_index = 0;
- } else {
- completions = Local<Array>::New(isolate, current_completions);
}
- if (current_index < completions->Length()) {
+ if (current_index < current_completions->Length()) {
+ HandleScope scope;
Handle<Integer> index = Integer::New(current_index);
- Handle<Value> str_obj = completions->Get(index);
+ Handle<Value> str_obj = current_completions->Get(index);
current_index++;
String::Utf8Value str(str_obj);
return strdup(*str);
diff --git a/src/data-flow.h b/src/data-flow.h
index 8ceccf6..7eeb794 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -215,8 +215,6 @@
};
GrowableBitVector() : bits_(NULL) { }
- GrowableBitVector(int length, Zone* zone)
- : bits_(new(zone) BitVector(length, zone)) { }
bool Contains(int value) const {
if (!InBitsRange(value)) return false;
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 14c1d73..723d3f6 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -534,9 +534,8 @@
output_count_(0),
jsframe_count_(0),
output_(NULL),
- deferred_objects_tagged_values_(0),
- deferred_objects_double_values_(0),
- deferred_objects_(0),
+ deferred_arguments_objects_values_(0),
+ deferred_arguments_objects_(0),
deferred_heap_numbers_(0),
trace_(false) {
// For COMPILED_STUBs called from builtins, the function pointer is a SMI
@@ -1567,14 +1566,15 @@
void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
ASSERT_NE(DEBUGGER, bailout_type_);
- // Handlify all tagged object values before triggering any allocation.
- List<Handle<Object> > values(deferred_objects_tagged_values_.length());
- for (int i = 0; i < deferred_objects_tagged_values_.length(); ++i) {
- values.Add(Handle<Object>(deferred_objects_tagged_values_[i], isolate_));
+ // Handlify all argument object values before triggering any allocation.
+ List<Handle<Object> > values(deferred_arguments_objects_values_.length());
+ for (int i = 0; i < deferred_arguments_objects_values_.length(); ++i) {
+ values.Add(Handle<Object>(deferred_arguments_objects_values_[i],
+ isolate_));
}
// Play it safe and clear all unhandlified values before we continue.
- deferred_objects_tagged_values_.Clear();
+ deferred_arguments_objects_values_.Clear();
// Materialize all heap numbers before looking at arguments because when the
// output frames are used to materialize arguments objects later on they need
@@ -1591,18 +1591,6 @@
Memory::Object_at(d.slot_address()) = *num;
}
- // Materialize all heap numbers required for arguments objects.
- for (int i = 0; i < values.length(); i++) {
- if (!values.at(i)->IsTheHole()) continue;
- double double_value = deferred_objects_double_values_[i];
- Handle<Object> num = isolate_->factory()->NewNumber(double_value);
- if (trace_) {
- PrintF("Materializing a new heap number %p [%e] for arguments object\n",
- reinterpret_cast<void*>(*num), double_value);
- }
- values.Set(i, num);
- }
-
// Materialize arguments objects one frame at a time.
for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) {
if (frame_index != 0) it->Advance();
@@ -1611,9 +1599,9 @@
Handle<JSObject> arguments;
for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
if (frame->GetExpression(i) == isolate_->heap()->arguments_marker()) {
- ObjectMaterializationDescriptor descriptor =
- deferred_objects_.RemoveLast();
- const int length = descriptor.object_length();
+ ArgumentsObjectMaterializationDescriptor descriptor =
+ deferred_arguments_objects_.RemoveLast();
+ const int length = descriptor.arguments_length();
if (arguments.is_null()) {
if (frame->has_adapted_arguments()) {
// Use the arguments adapter frame we just built to materialize the
@@ -1707,7 +1695,7 @@
#endif
-static const char* TraceValueType(bool is_smi, bool is_native = false) {
+static const char* TraceValueType(bool is_smi, bool is_native) {
if (is_native) {
return "native";
} else if (is_smi) {
@@ -1718,204 +1706,6 @@
}
-void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
- int object_opcode,
- int field_index) {
- disasm::NameConverter converter;
- Address object_slot = deferred_objects_.last().slot_address();
-
- // Ignore commands marked as duplicate and act on the first non-duplicate.
- Translation::Opcode opcode =
- static_cast<Translation::Opcode>(iterator->Next());
- while (opcode == Translation::DUPLICATE) {
- opcode = static_cast<Translation::Opcode>(iterator->Next());
- iterator->Skip(Translation::NumberOfOperandsFor(opcode));
- opcode = static_cast<Translation::Opcode>(iterator->Next());
- }
-
- switch (opcode) {
- case Translation::BEGIN:
- case Translation::JS_FRAME:
- case Translation::ARGUMENTS_ADAPTOR_FRAME:
- case Translation::CONSTRUCT_STUB_FRAME:
- case Translation::GETTER_STUB_FRAME:
- case Translation::SETTER_STUB_FRAME:
- case Translation::COMPILED_STUB_FRAME:
- case Translation::ARGUMENTS_OBJECT:
- case Translation::DUPLICATE:
- UNREACHABLE();
- return;
-
- case Translation::REGISTER: {
- int input_reg = iterator->Next();
- intptr_t input_value = input_->GetRegister(input_reg);
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("0x%08" V8PRIxPTR " ; %s ", input_value,
- converter.NameOfCPURegister(input_reg));
- reinterpret_cast<Object*>(input_value)->ShortPrint();
- PrintF("\n");
- }
- AddObjectTaggedValue(input_value);
- return;
- }
-
- case Translation::INT32_REGISTER: {
- int input_reg = iterator->Next();
- intptr_t value = input_->GetRegister(input_reg);
- bool is_smi = Smi::IsValid(value);
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("%" V8PRIdPTR " ; %s (%s)\n", value,
- converter.NameOfCPURegister(input_reg),
- TraceValueType(is_smi));
- }
- if (is_smi) {
- intptr_t tagged_value =
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
- AddObjectTaggedValue(tagged_value);
- } else {
- double double_value = static_cast<double>(static_cast<int32_t>(value));
- AddObjectDoubleValue(double_value);
- }
- return;
- }
-
- case Translation::UINT32_REGISTER: {
- int input_reg = iterator->Next();
- uintptr_t value = static_cast<uintptr_t>(input_->GetRegister(input_reg));
- bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("%" V8PRIdPTR " ; uint %s (%s)\n", value,
- converter.NameOfCPURegister(input_reg),
- TraceValueType(is_smi));
- }
- if (is_smi) {
- intptr_t tagged_value =
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
- AddObjectTaggedValue(tagged_value);
- } else {
- double double_value = static_cast<double>(static_cast<uint32_t>(value));
- AddObjectDoubleValue(double_value);
- }
- return;
- }
-
- case Translation::DOUBLE_REGISTER: {
- int input_reg = iterator->Next();
- double value = input_->GetDoubleRegister(input_reg);
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("%e ; %s\n", value,
- DoubleRegister::AllocationIndexToString(input_reg));
- }
- AddObjectDoubleValue(value);
- return;
- }
-
- case Translation::STACK_SLOT: {
- int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
- intptr_t input_value = input_->GetFrameSlot(input_offset);
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("0x%08" V8PRIxPTR " ; [sp + %d] ", input_value, input_offset);
- reinterpret_cast<Object*>(input_value)->ShortPrint();
- PrintF("\n");
- }
- AddObjectTaggedValue(input_value);
- return;
- }
-
- case Translation::INT32_STACK_SLOT: {
- int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
- intptr_t value = input_->GetFrameSlot(input_offset);
- bool is_smi = Smi::IsValid(value);
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("%" V8PRIdPTR " ; [sp + %d] (%s)\n",
- value, input_offset, TraceValueType(is_smi));
- }
- if (is_smi) {
- intptr_t tagged_value =
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
- AddObjectTaggedValue(tagged_value);
- } else {
- double double_value = static_cast<double>(static_cast<int32_t>(value));
- AddObjectDoubleValue(double_value);
- }
- return;
- }
-
- case Translation::UINT32_STACK_SLOT: {
- int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
- uintptr_t value =
- static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
- bool is_smi = (value <= static_cast<uintptr_t>(Smi::kMaxValue));
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
- value, input_offset, TraceValueType(is_smi));
- }
- if (is_smi) {
- intptr_t tagged_value =
- reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
- AddObjectTaggedValue(tagged_value);
- } else {
- double double_value = static_cast<double>(static_cast<uint32_t>(value));
- AddObjectDoubleValue(double_value);
- }
- return;
- }
-
- case Translation::DOUBLE_STACK_SLOT: {
- int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
- double value = input_->GetDoubleFrameSlot(input_offset);
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- PrintF("%e ; [sp + %d]\n", value, input_offset);
- }
- AddObjectDoubleValue(value);
- return;
- }
-
- case Translation::LITERAL: {
- Object* literal = ComputeLiteral(iterator->Next());
- if (trace_) {
- PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ",
- reinterpret_cast<intptr_t>(object_slot),
- field_index);
- literal->ShortPrint();
- PrintF(" ; literal\n");
- }
- intptr_t value = reinterpret_cast<intptr_t>(literal);
- AddObjectTaggedValue(value);
- return;
- }
- }
-}
-
-
void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
int frame_index,
unsigned output_offset,
@@ -1968,6 +1758,7 @@
intptr_t value = input_->GetRegister(input_reg);
bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
Smi::IsValid(value);
+
if (trace_) {
PrintF(
" 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
@@ -2045,7 +1836,8 @@
case Translation::STACK_SLOT: {
int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+ unsigned input_offset =
+ input_->GetOffsetFromSlotIndex(input_slot_index);
intptr_t input_value = input_->GetFrameSlot(input_offset);
if (trace_) {
PrintF(" 0x%08" V8PRIxPTR ": ",
@@ -2063,7 +1855,8 @@
case Translation::INT32_STACK_SLOT: {
int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+ unsigned input_offset =
+ input_->GetOffsetFromSlotIndex(input_slot_index);
intptr_t value = input_->GetFrameSlot(input_offset);
bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
Smi::IsValid(value);
@@ -2095,7 +1888,8 @@
case Translation::UINT32_STACK_SLOT: {
int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+ unsigned input_offset =
+ input_->GetOffsetFromSlotIndex(input_slot_index);
uintptr_t value =
static_cast<uintptr_t>(input_->GetFrameSlot(input_offset));
bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) &&
@@ -2128,7 +1922,8 @@
case Translation::DOUBLE_STACK_SLOT: {
int input_slot_index = iterator->Next();
- unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index);
+ unsigned input_offset =
+ input_->GetOffsetFromSlotIndex(input_slot_index);
double value = input_->GetDoubleFrameSlot(input_offset);
if (trace_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n",
@@ -2159,24 +1954,31 @@
}
case Translation::ARGUMENTS_OBJECT: {
- int length = iterator->Next();
+ bool args_known = iterator->Next();
+ int args_index = iterator->Next() + 1; // Skip receiver.
+ int args_length = iterator->Next() - 1; // Skip receiver.
if (trace_) {
PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ",
output_[frame_index]->GetTop() + output_offset,
output_offset);
isolate_->heap()->arguments_marker()->ShortPrint();
- PrintF(" ; arguments object (length = %d)\n", length);
+ PrintF(" ; %sarguments object\n", args_known ? "" : "dummy ");
}
// Use the arguments marker value as a sentinel and fill in the arguments
// object after the deoptimized frame is built.
intptr_t value = reinterpret_cast<intptr_t>(
isolate_->heap()->arguments_marker());
- AddObjectStart(output_[frame_index]->GetTop() + output_offset, length);
+ AddArgumentsObject(
+ output_[frame_index]->GetTop() + output_offset, args_length);
output_[frame_index]->SetFrameSlot(output_offset, value);
- // We save the argument values on the side and materialize the actual
- // arguments object after the deoptimized frame is built.
- for (int i = 0; i < length; i++) {
- DoTranslateObject(iterator, Translation::ARGUMENTS_OBJECT, i);
+ // We save the tagged argument values on the side and materialize the
+ // actual arguments object after the deoptimized frame is built.
+ for (int i = 0; i < args_length; i++) {
+ unsigned input_offset = input_->GetOffsetFromSlotIndex(args_index + i);
+ intptr_t input_value = args_known
+ ? input_->GetFrameSlot(input_offset)
+ : reinterpret_cast<intptr_t>(isolate_->heap()->the_hole_value());
+ AddArgumentsObjectValue(input_value);
}
return;
}
@@ -2522,22 +2324,15 @@
}
-void Deoptimizer::AddObjectStart(intptr_t slot_address, int length) {
- ObjectMaterializationDescriptor object_desc(
- reinterpret_cast<Address>(slot_address), length);
- deferred_objects_.Add(object_desc);
+void Deoptimizer::AddArgumentsObject(intptr_t slot_address, int argc) {
+ ArgumentsObjectMaterializationDescriptor object_desc(
+ reinterpret_cast<Address>(slot_address), argc);
+ deferred_arguments_objects_.Add(object_desc);
}
-void Deoptimizer::AddObjectTaggedValue(intptr_t value) {
- deferred_objects_tagged_values_.Add(reinterpret_cast<Object*>(value));
- deferred_objects_double_values_.Add(isolate()->heap()->nan_value()->value());
-}
-
-
-void Deoptimizer::AddObjectDoubleValue(double value) {
- deferred_objects_tagged_values_.Add(isolate()->heap()->the_hole_value());
- deferred_objects_double_values_.Add(value);
+void Deoptimizer::AddArgumentsObjectValue(intptr_t value) {
+ deferred_arguments_objects_values_.Add(reinterpret_cast<Object*>(value));
}
@@ -2761,12 +2556,6 @@
}
-void Translation::BeginArgumentsObject(int args_length) {
- buffer_->Add(ARGUMENTS_OBJECT, zone());
- buffer_->Add(args_length, zone());
-}
-
-
void Translation::StoreRegister(Register reg) {
buffer_->Add(REGISTER, zone());
buffer_->Add(reg.code(), zone());
@@ -2821,6 +2610,16 @@
}
+void Translation::StoreArgumentsObject(bool args_known,
+ int args_index,
+ int args_length) {
+ buffer_->Add(ARGUMENTS_OBJECT, zone());
+ buffer_->Add(args_known, zone());
+ buffer_->Add(args_index, zone());
+ buffer_->Add(args_length, zone());
+}
+
+
void Translation::MarkDuplicate() {
buffer_->Add(DUPLICATE, zone());
}
@@ -2832,7 +2631,6 @@
return 0;
case GETTER_STUB_FRAME:
case SETTER_STUB_FRAME:
- case ARGUMENTS_OBJECT:
case REGISTER:
case INT32_REGISTER:
case UINT32_REGISTER:
@@ -2849,6 +2647,7 @@
case CONSTRUCT_STUB_FRAME:
return 2;
case JS_FRAME:
+ case ARGUMENTS_OBJECT:
return 3;
}
UNREACHABLE();
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index 5ca635c..5569f7f 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -75,17 +75,17 @@
};
-class ObjectMaterializationDescriptor BASE_EMBEDDED {
+class ArgumentsObjectMaterializationDescriptor BASE_EMBEDDED {
public:
- ObjectMaterializationDescriptor(Address slot_address, int length)
- : slot_address_(slot_address), object_length_(length) { }
+ ArgumentsObjectMaterializationDescriptor(Address slot_address, int argc)
+ : slot_address_(slot_address), arguments_length_(argc) { }
Address slot_address() const { return slot_address_; }
- int object_length() const { return object_length_; }
+ int arguments_length() const { return arguments_length_; }
private:
Address slot_address_;
- int object_length_;
+ int arguments_length_;
};
@@ -369,10 +369,6 @@
void DoComputeCompiledStubFrame(TranslationIterator* iterator,
int frame_index);
- void DoTranslateObject(TranslationIterator* iterator,
- int object_opcode,
- int field_index);
-
enum DeoptimizerTranslatedValueType {
TRANSLATED_VALUE_IS_NATIVE,
TRANSLATED_VALUE_IS_TAGGED
@@ -398,9 +394,8 @@
Object* ComputeLiteral(int index) const;
- void AddObjectStart(intptr_t slot_address, int argc);
- void AddObjectTaggedValue(intptr_t value);
- void AddObjectDoubleValue(double value);
+ void AddArgumentsObject(intptr_t slot_address, int argc);
+ void AddArgumentsObjectValue(intptr_t value);
void AddDoubleValue(intptr_t slot_address, double value);
static void GenerateDeoptimizationEntries(
@@ -451,9 +446,8 @@
// Array of output frame descriptions.
FrameDescription** output_;
- List<Object*> deferred_objects_tagged_values_;
- List<double> deferred_objects_double_values_;
- List<ObjectMaterializationDescriptor> deferred_objects_;
+ List<Object*> deferred_arguments_objects_values_;
+ List<ArgumentsObjectMaterializationDescriptor> deferred_arguments_objects_;
List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
#ifdef DEBUG
DisallowHeapAllocation* disallow_heap_allocation_;
@@ -704,7 +698,6 @@
SETTER_STUB_FRAME,
ARGUMENTS_ADAPTOR_FRAME,
COMPILED_STUB_FRAME,
- ARGUMENTS_OBJECT,
REGISTER,
INT32_REGISTER,
UINT32_REGISTER,
@@ -714,6 +707,7 @@
UINT32_STACK_SLOT,
DOUBLE_STACK_SLOT,
LITERAL,
+ ARGUMENTS_OBJECT,
// A prefix indicating that the next command is a duplicate of the one
// that follows it.
@@ -739,7 +733,6 @@
void BeginConstructStubFrame(int literal_id, unsigned height);
void BeginGetterStubFrame(int literal_id);
void BeginSetterStubFrame(int literal_id);
- void BeginArgumentsObject(int args_length);
void StoreRegister(Register reg);
void StoreInt32Register(Register reg);
void StoreUint32Register(Register reg);
@@ -749,6 +742,7 @@
void StoreUint32StackSlot(int index);
void StoreDoubleStackSlot(int index);
void StoreLiteral(int literal_id);
+ void StoreArgumentsObject(bool args_known, int args_index, int args_length);
void MarkDuplicate();
Zone* zone() const { return zone_; }
diff --git a/src/full-codegen.h b/src/full-codegen.h
index dc5ac6a..969a98d 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -123,15 +123,14 @@
static const int kMaxBackEdgeWeight = 127;
- // Platform-specific code size multiplier.
#if V8_TARGET_ARCH_IA32
- static const int kCodeSizeMultiplier = 100;
+ static const int kBackEdgeDistanceUnit = 100;
#elif V8_TARGET_ARCH_X64
- static const int kCodeSizeMultiplier = 162;
+ static const int kBackEdgeDistanceUnit = 162;
#elif V8_TARGET_ARCH_ARM
- static const int kCodeSizeMultiplier = 142;
+ static const int kBackEdgeDistanceUnit = 142;
#elif V8_TARGET_ARCH_MIPS
- static const int kCodeSizeMultiplier = 142;
+ static const int kBackEdgeDistanceUnit = 142;
#else
#error Unsupported target architecture.
#endif
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 03a91c4..d691299 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2016,9 +2016,6 @@
};
-class HArgumentsObject;
-
-
class HEnterInlined: public HTemplateInstruction<0> {
public:
HEnterInlined(Handle<JSFunction> closure,
@@ -2026,7 +2023,7 @@
FunctionLiteral* function,
InliningKind inlining_kind,
Variable* arguments_var,
- HArgumentsObject* arguments_object,
+ ZoneList<HValue*>* arguments_values,
bool undefined_receiver,
Zone* zone)
: closure_(closure),
@@ -2035,7 +2032,7 @@
function_(function),
inlining_kind_(inlining_kind),
arguments_var_(arguments_var),
- arguments_object_(arguments_object),
+ arguments_values_(arguments_values),
undefined_receiver_(undefined_receiver),
return_targets_(2, zone) {
}
@@ -2058,7 +2055,7 @@
}
Variable* arguments_var() { return arguments_var_; }
- HArgumentsObject* arguments_object() { return arguments_object_; }
+ ZoneList<HValue*>* arguments_values() { return arguments_values_; }
DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
@@ -2069,7 +2066,7 @@
FunctionLiteral* function_;
InliningKind inlining_kind_;
Variable* arguments_var_;
- HArgumentsObject* arguments_object_;
+ ZoneList<HValue*>* arguments_values_;
bool undefined_receiver_;
ZoneList<HBasicBlock*> return_targets_;
};
@@ -3205,43 +3202,25 @@
class HArgumentsObject: public HTemplateInstruction<0> {
public:
- HArgumentsObject(int count, Zone* zone) : values_(count, zone) {
+ HArgumentsObject() {
set_representation(Representation::Tagged());
SetFlag(kIsArguments);
}
- const ZoneList<HValue*>* arguments_values() const { return &values_; }
- int arguments_count() const { return values_.length(); }
-
- void AddArgument(HValue* argument, Zone* zone) {
- values_.Add(NULL, zone); // Resize list.
- SetOperandAt(values_.length() - 1, argument);
- }
-
- virtual int OperandCount() { return values_.length(); }
- virtual HValue* OperandAt(int index) const { return values_[index]; }
-
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value) {
- values_[index] = value;
- }
-
private:
virtual bool IsDeletable() const { return true; }
-
- ZoneList<HValue*> values_;
};
class HConstant: public HTemplateInstruction<0> {
public:
- HConstant(Handle<Object> handle, Representation r = Representation::None());
+ HConstant(Handle<Object> handle, Representation r);
HConstant(int32_t value,
Representation r = Representation::None(),
bool is_not_in_new_space = true,
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 74bf489..0676555 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -709,9 +709,13 @@
HInstruction* HGraphBuilder::IfBuilder::IfCompare(
HValue* left,
HValue* right,
- Token::Value token) {
+ Token::Value token,
+ Representation input_representation) {
HCompareIDAndBranch* compare =
new(zone()) HCompareIDAndBranch(left, right, token);
+ compare->set_observed_input_representation(input_representation,
+ input_representation);
+ compare->AssumeRepresentation(input_representation);
AddCompare(compare);
return compare;
}
@@ -1000,7 +1004,7 @@
HValue* context = environment()->LookupContext();
int num_parameters = graph()->info()->num_parameters();
HValue* params = AddInstruction(new(graph()->zone())
- HConstant(num_parameters));
+ HConstant(num_parameters, Representation::Integer32()));
HReturn* return_instruction = new(graph()->zone())
HReturn(value, context, params);
current_block()->FinishExit(return_instruction);
@@ -1165,6 +1169,7 @@
if (is_js_array) {
HValue* new_length = AddInstruction(
HAdd::New(zone, context, length, graph_->GetConstant1()));
+ new_length->AssumeRepresentation(Representation::Integer32());
new_length->ClearFlag(HValue::kCanOverflow);
Representation representation = IsFastElementsKind(kind)
@@ -1337,16 +1342,20 @@
int elements_size = IsFastDoubleElementsKind(kind)
? kDoubleSize : kPointerSize;
- HConstant* elements_size_value = new(zone) HConstant(elements_size);
+ HConstant* elements_size_value =
+ new(zone) HConstant(elements_size, Representation::Integer32());
AddInstruction(elements_size_value);
HValue* mul = AddInstruction(
HMul::New(zone, context, capacity, elements_size_value));
+ mul->AssumeRepresentation(Representation::Integer32());
mul->ClearFlag(HValue::kCanOverflow);
- HConstant* header_size = new(zone) HConstant(FixedArray::kHeaderSize);
+ HConstant* header_size =
+ new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32());
AddInstruction(header_size);
HValue* total_size = AddInstruction(
HAdd::New(zone, context, mul, header_size));
+ total_size->AssumeRepresentation(Representation::Integer32());
total_size->ClearFlag(HValue::kCanOverflow);
HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
@@ -1404,7 +1413,9 @@
AddStore(array, HObjectAccess::ForMap(), array_map);
HConstant* empty_fixed_array =
- new(zone()) HConstant(isolate()->factory()->empty_fixed_array());
+ new(zone()) HConstant(
+ Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
+ Representation::Tagged());
AddInstruction(empty_fixed_array);
HObjectAccess access = HObjectAccess::ForPropertiesPointer();
@@ -1443,16 +1454,20 @@
HValue* half_old_capacity =
AddInstruction(HShr::New(zone, context, old_capacity,
graph_->GetConstant1()));
+ half_old_capacity->AssumeRepresentation(Representation::Integer32());
half_old_capacity->ClearFlag(HValue::kCanOverflow);
HValue* new_capacity = AddInstruction(
HAdd::New(zone, context, half_old_capacity, old_capacity));
+ new_capacity->AssumeRepresentation(Representation::Integer32());
new_capacity->ClearFlag(HValue::kCanOverflow);
- HValue* min_growth = AddInstruction(new(zone) HConstant(16));
+ HValue* min_growth =
+ AddInstruction(new(zone) HConstant(16, Representation::Integer32()));
new_capacity = AddInstruction(
HAdd::New(zone, context, new_capacity, min_growth));
+ new_capacity->AssumeRepresentation(Representation::Integer32());
new_capacity->ClearFlag(HValue::kCanOverflow);
return new_capacity;
@@ -1508,8 +1523,10 @@
double nan_double = FixedDoubleArray::hole_nan_as_double();
Zone* zone = this->zone();
HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
- ? AddInstruction(new(zone) HConstant(factory->the_hole_value()))
- : AddInstruction(new(zone) HConstant(nan_double));
+ ? AddInstruction(new(zone) HConstant(factory->the_hole_value(),
+ Representation::Tagged()))
+ : AddInstruction(new(zone) HConstant(nan_double,
+ Representation::Double()));
// Special loop unfolding case
static const int kLoopUnfoldLimit = 4;
@@ -1622,7 +1639,8 @@
HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
// Allocate both the JS array and the elements array in one big
// allocation. This avoids multiple limit checks.
- HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size));
+ HValue* size_in_bytes =
+ AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
HInstruction* object =
AddInstruction(new(zone) HAllocate(context,
size_in_bytes,
@@ -1745,7 +1763,7 @@
HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) {
HInstruction* native_context = BuildGetNativeContext(context);
HInstruction* index = AddInstruction(new(zone())
- HConstant(Context::ARRAY_FUNCTION_INDEX));
+ HConstant(Context::ARRAY_FUNCTION_INDEX, Representation::Integer32()));
return AddInstruction(new (zone())
HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS));
@@ -1781,13 +1799,13 @@
HInstruction* native_context = builder()->BuildGetNativeContext(context);
HInstruction* index = builder()->AddInstruction(new(zone())
- HConstant(Context::JS_ARRAY_MAPS_INDEX));
+ HConstant(Context::JS_ARRAY_MAPS_INDEX, Representation::Integer32()));
HInstruction* map_array = builder()->AddInstruction(new(zone())
HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS));
HInstruction* kind_index = builder()->AddInstruction(new(zone())
- HConstant(kind_));
+ HConstant(kind_, Representation::Integer32()));
return builder()->AddInstruction(new(zone())
HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS));
@@ -1820,16 +1838,20 @@
base_size += FixedArray::kHeaderSize;
}
- HInstruction* elements_size_value = new(zone()) HConstant(elements_size());
+ HInstruction* elements_size_value = new(zone())
+ HConstant(elements_size(), Representation::Integer32());
AddInstruction(elements_size_value);
HInstruction* mul = HMul::New(zone(), context, length_node,
elements_size_value);
+ mul->AssumeRepresentation(Representation::Integer32());
mul->ClearFlag(HValue::kCanOverflow);
AddInstruction(mul);
- HInstruction* base = new(zone()) HConstant(base_size);
+ HInstruction* base = new(zone()) HConstant(base_size,
+ Representation::Integer32());
AddInstruction(base);
HInstruction* total_size = HAdd::New(zone(), context, base, mul);
+ total_size->AssumeRepresentation(Representation::Integer32());
total_size->ClearFlag(HValue::kCanOverflow);
AddInstruction(total_size);
return total_size;
@@ -1846,7 +1868,8 @@
? FixedDoubleArray::SizeFor(initial_capacity())
: FixedArray::SizeFor(initial_capacity());
- HConstant* array_size = new(zone()) HConstant(base_size);
+ HConstant* array_size =
+ new(zone()) HConstant(base_size, Representation::Integer32());
AddInstruction(array_size);
return array_size;
}
@@ -1854,7 +1877,8 @@
HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
- HConstant* capacity = new(zone()) HConstant(initial_capacity());
+ HConstant* capacity =
+ new(zone()) HConstant(initial_capacity(), Representation::Integer32());
AddInstruction(capacity);
return AllocateArray(size_in_bytes,
capacity,
@@ -1932,7 +1956,8 @@
HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
Handle<Map> map) {
- HValue* constant = AddInstruction(new(zone()) HConstant(map));
+ HValue* constant =
+ AddInstruction(new(zone()) HConstant(map, Representation::Tagged()));
HStoreNamedField *instr =
new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant);
AddInstruction(instr);
@@ -3521,7 +3546,6 @@
function_return_(NULL),
test_context_(NULL),
entry_(NULL),
- arguments_object_(NULL),
arguments_elements_(NULL),
outer_(owner->function_state()) {
if (outer_ != NULL) {
@@ -4669,22 +4693,22 @@
void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
HConstant* undefined_constant = new(zone()) HConstant(
- isolate()->factory()->undefined_value());
+ isolate()->factory()->undefined_value(), Representation::Tagged());
AddInstruction(undefined_constant);
graph()->set_undefined_constant(undefined_constant);
- // Create an arguments object containing the initial parameters. Set the
- // initial values of parameters including "this" having parameter index 0.
+ HArgumentsObject* object = new(zone()) HArgumentsObject;
+ AddInstruction(object);
+ graph()->SetArgumentsObject(object);
+
+ // Set the initial values of parameters including "this". "This" has
+ // parameter index 0.
ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
- HArgumentsObject* arguments_object =
- new(zone()) HArgumentsObject(environment()->parameter_count(), zone());
+
for (int i = 0; i < environment()->parameter_count(); ++i) {
HInstruction* parameter = AddInstruction(new(zone()) HParameter(i));
- arguments_object->AddArgument(parameter, zone());
environment()->Bind(i, parameter);
}
- AddInstruction(arguments_object);
- graph()->SetArgumentsObject(arguments_object);
// First special is HContext.
HInstruction* context = AddInstruction(new(zone()) HContext);
@@ -5008,7 +5032,7 @@
label_value,
Token::EQ_STRICT);
compare_->set_observed_input_representation(
- Representation::Smi(), Representation::Smi());
+ Representation::Integer32(), Representation::Integer32());
compare = compare_;
} else {
compare = new(zone()) HStringCompareAndBranch(context, tag_value,
@@ -5373,7 +5397,7 @@
HCompareIDAndBranch* compare_index =
new(zone()) HCompareIDAndBranch(index, limit, Token::LT);
compare_index->set_observed_input_representation(
- Representation::Smi(), Representation::Smi());
+ Representation::Integer32(), Representation::Integer32());
HBasicBlock* loop_body = graph()->CreateBasicBlock();
HBasicBlock* loop_successor = graph()->CreateBasicBlock();
@@ -5595,7 +5619,8 @@
Handle<Object> constant_value =
isolate()->factory()->GlobalConstantFor(variable->name());
if (!constant_value.is_null()) {
- HConstant* instr = new(zone()) HConstant(constant_value);
+ HConstant* instr =
+ new(zone()) HConstant(constant_value, Representation::Tagged());
return ast_context()->ReturnInstruction(instr, expr->id());
}
@@ -5655,7 +5680,8 @@
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- HConstant* instr = new(zone()) HConstant(expr->handle());
+ HConstant* instr =
+ new(zone()) HConstant(expr->handle(), Representation::None());
return ast_context()->ReturnInstruction(instr, expr->id());
}
@@ -5880,13 +5906,13 @@
? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(closure_literals))));
+ new(zone()) HConstant(closure_literals, Representation::Tagged()))));
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(literal_index))));
+ new(zone()) HConstant(literal_index, Representation::Tagged()))));
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(constant_properties))));
+ new(zone()) HConstant(constant_properties, Representation::Tagged()))));
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(flags))));
+ new(zone()) HConstant(flags, Representation::Tagged()))));
Runtime::FunctionId function_id =
(expr->depth() > 1 || expr->may_store_doubles())
@@ -6044,22 +6070,22 @@
boilerplate_elements_kind, true)) {
IfBuilder builder(this);
HValue* boilerplate = AddInstruction(new(zone())
- HConstant(original_boilerplate_object));
+ HConstant(original_boilerplate_object, Representation::Tagged()));
HValue* elements_kind = AddInstruction(new(zone())
HElementsKind(boilerplate));
HValue* expected_kind = AddInstruction(new(zone())
- HConstant(boilerplate_elements_kind));
+ HConstant(boilerplate_elements_kind, Representation::Integer32()));
builder.IfCompare(elements_kind, expected_kind, Token::EQ);
builder.Then();
builder.ElseDeopt();
}
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(literals))));
+ new(zone()) HConstant(literals, Representation::Tagged()))));
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(literal_index))));
+ new(zone()) HConstant(literal_index, Representation::Tagged()))));
AddInstruction(new(zone()) HPushArgument(AddInstruction(
- new(zone()) HConstant(constants))));
+ new(zone()) HConstant(constants, Representation::Tagged()))));
Runtime::FunctionId function_id = (expr->depth() > 1)
? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
@@ -6073,8 +6099,6 @@
// The array is expected in the bailout environment during computation
// of the property values and is the value of the entire expression.
Push(literal);
- // The literal index is on the stack, too.
- Push(AddInstruction(new(zone()) HConstant(expr->literal_index())));
HInstruction* elements = NULL;
@@ -6112,8 +6136,6 @@
AddSimulate(expr->GetIdForElement(i));
}
-
- Drop(1); // array literal index
return ast_context()->ReturnValue(Pop());
}
@@ -6217,7 +6239,7 @@
// The store requires a mutable HeapNumber to be allocated.
NoObservableSideEffectsScope no_side_effects(this);
HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant(
- HeapNumber::kSize));
+ HeapNumber::kSize, Representation::Integer32()));
HInstruction* double_box = AddInstruction(new(zone()) HAllocate(
environment()->LookupContext(), heap_number_size,
HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE));
@@ -6293,13 +6315,43 @@
}
-HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
+bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad(
Property* expr,
HValue* object,
SmallMapList* types,
Handle<String> name) {
+ if (!name->Equals(isolate()->heap()->length_string())) return false;
+
+ for (int i = 0; i < types->length(); i++) {
+ if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
+ }
+
+ BuildCheckNonSmi(object);
+
+ HInstruction* typecheck =
+ AddInstruction(HCheckMaps::New(object, types, zone()));
+ HInstruction* instr = new(zone())
+ HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck);
+
+ instr->set_position(expr->position());
+ ast_context()->ReturnInstruction(instr, expr->id());
+ return true;
+}
+
+
+void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
+ HValue* object,
+ SmallMapList* types,
+ Handle<String> name) {
+
+ if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
+ return;
+
+ BuildCheckNonSmi(object);
+
// Use monomorphic load if property lookup results in the same field index
// for all maps. Requires special map check on the set of all handled maps.
+ HInstruction* instr = NULL;
LookupResult lookup(isolate());
int count;
Representation representation = Representation::None();
@@ -6330,25 +6382,12 @@
}
}
- if (count != types->length()) return NULL;
-
- // Everything matched; can use monomorphic load.
- BuildCheckNonSmi(object);
- AddInstruction(HCheckMaps::New(object, types, zone()));
- return BuildLoadNamedField(object, access, representation);
-}
-
-
-void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
- Property* expr,
- HValue* object,
- SmallMapList* types,
- Handle<String> name) {
- HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
- expr, object, types, name);
- if (instr == NULL) {
+ if (count == types->length()) {
+ // Everything matched; can use monomorphic load.
+ AddInstruction(HCheckMaps::New(object, types, zone()));
+ instr = BuildLoadNamedField(object, access, representation);
+ } else {
// Something did not match; must use a polymorphic load.
- BuildCheckNonSmi(object);
HValue* context = environment()->LookupContext();
instr = new(zone()) HLoadNamedFieldPolymorphic(
context, object, types, name, zone());
@@ -6643,11 +6682,10 @@
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
Handle<Map> map;
- HInstruction* load = NULL;
- SmallMapList* types = prop->GetReceiverTypes();
+ HInstruction* load;
bool monomorphic = prop->IsMonomorphic();
if (monomorphic) {
- map = types->first();
+ map = prop->GetReceiverTypes()->first();
// We can't generate code for a monomorphic dict mode load so
// just pretend it is not monomorphic.
if (map->is_dictionary_map()) monomorphic = false;
@@ -6660,10 +6698,9 @@
} else {
load = BuildLoadNamedMonomorphic(object, name, prop, map);
}
- } else if (types != NULL && types->length() > 1) {
- load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
+ } else {
+ load = BuildLoadNamedGeneric(object, name, prop);
}
- if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
PushAndAdd(load);
if (load->HasObservableSideEffects()) {
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
@@ -6929,8 +6966,6 @@
Property* expr) {
if (expr->IsUninitialized()) {
AddSoftDeoptimize();
- } else {
- // OS::DebugBreak();
}
HValue* context = environment()->LookupContext();
return new(zone()) HLoadNamedGeneric(context, object, name);
@@ -6978,7 +7013,7 @@
if (lookup.IsConstantFunction()) {
AddCheckMap(object, map);
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
- return new(zone()) HConstant(function);
+ return new(zone()) HConstant(function, Representation::Tagged());
}
// Handle a load from a known field somewhere in the prototype chain.
@@ -6990,7 +7025,8 @@
AddCheckMap(object, map);
AddInstruction(new(zone()) HCheckPrototypeMaps(
prototype, holder, zone(), top_info()));
- HValue* holder_value = AddInstruction(new(zone()) HConstant(holder));
+ HValue* holder_value = AddInstruction(new(zone())
+ HConstant(holder, Representation::Tagged()));
return BuildLoadNamedField(holder_value,
HObjectAccess::ForField(holder_map, &lookup, name),
ComputeLoadStoreRepresentation(map, &lookup));
@@ -7005,7 +7041,7 @@
AddInstruction(new(zone()) HCheckPrototypeMaps(
prototype, holder, zone(), top_info()));
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
- return new(zone()) HConstant(function);
+ return new(zone()) HConstant(function, Representation::Tagged());
}
// No luck, do a generic load.
@@ -7392,8 +7428,7 @@
HEnterInlined* entry = function_state()->entry();
entry->set_arguments_pushed();
- HArgumentsObject* arguments = entry->arguments_object();
- const ZoneList<HValue*>* arguments_values = arguments->arguments_values();
+ ZoneList<HValue*>* arguments_values = entry->arguments_values();
HInstruction* insert_after = entry;
for (int i = 0; i < arguments_values->length(); i++) {
@@ -7986,27 +8021,25 @@
// TODO(kmillikin): implement the same inlining on other platforms so we
// can remove the unsightly ifdefs in this function.
HConstant* context =
- new(zone()) HConstant(Handle<Context>(target->context()));
+ new(zone()) HConstant(Handle<Context>(target->context()),
+ Representation::Tagged());
AddInstruction(context);
inner_env->BindContext(context);
#endif
AddSimulate(return_id);
current_block()->UpdateEnvironment(inner_env);
- HArgumentsObject* arguments_object = NULL;
+ ZoneList<HValue*>* arguments_values = NULL;
- // If the function uses arguments object create and bind one, also copy
- // current arguments values to use them for materialization.
+ // If the function uses arguments copy current arguments values
+ // to use them for materialization.
if (function->scope()->arguments() != NULL) {
- ASSERT(function->scope()->arguments()->IsStackAllocated());
HEnvironment* arguments_env = inner_env->arguments_environment();
int arguments_count = arguments_env->parameter_count();
- arguments_object = new(zone()) HArgumentsObject(arguments_count, zone());
- inner_env->Bind(function->scope()->arguments(), arguments_object);
+ arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone());
for (int i = 0; i < arguments_count; i++) {
- arguments_object->AddArgument(arguments_env->Lookup(i), zone());
+ arguments_values->Add(arguments_env->Lookup(i), zone());
}
- AddInstruction(arguments_object);
}
HEnterInlined* enter_inlined =
@@ -8015,12 +8048,20 @@
function,
function_state()->inlining_kind(),
function->scope()->arguments(),
- arguments_object,
+ arguments_values,
undefined_receiver,
zone());
function_state()->set_entry(enter_inlined);
AddInstruction(enter_inlined);
+ // If the function uses arguments object create and bind one.
+ if (function->scope()->arguments() != NULL) {
+ ASSERT(function->scope()->arguments()->IsStackAllocated());
+ inner_env->Bind(function->scope()->arguments(),
+ graph()->GetArgumentsObject());
+ }
+
+
VisitDeclarations(target_info.scope()->declarations());
VisitStatements(function->body());
if (HasStackOverflow()) {
@@ -8326,14 +8367,16 @@
result =
HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
} else if (exponent == -0.5) {
- HValue* one = graph()->GetConstant1();
+ HConstant* double_one = new(zone()) HConstant(
+ 1, Representation::Double());
+ AddInstruction(double_one);
HInstruction* sqrt =
HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
AddInstruction(sqrt);
// MathPowHalf doesn't have side effects so there's no need for
// an environment simulation here.
ASSERT(!sqrt->HasObservableSideEffects());
- result = HDiv::New(zone(), context, one, sqrt);
+ result = HDiv::New(zone(), context, double_one, sqrt);
} else if (exponent == 2.0) {
result = HMul::New(zone(), context, left, left);
}
@@ -8450,10 +8493,13 @@
} else {
// We are inside inlined function and we know exactly what is inside
// arguments object. But we need to be able to materialize at deopt.
+ // TODO(mstarzinger): For now we just ensure arguments are pushed
+ // right after HEnterInlined, but we could be smarter about this.
+ EnsureArgumentsArePushedForAccess();
ASSERT_EQ(environment()->arguments_environment()->parameter_count(),
- function_state()->entry()->arguments_object()->arguments_count());
- HArgumentsObject* args = function_state()->entry()->arguments_object();
- const ZoneList<HValue*>* arguments_values = args->arguments_values();
+ function_state()->entry()->arguments_values()->length());
+ HEnterInlined* entry = function_state()->entry();
+ ZoneList<HValue*>* arguments_values = entry->arguments_values();
int arguments_count = arguments_values->length();
PushAndAdd(new(zone()) HWrapReceiver(receiver, function));
for (int i = 1; i < arguments_count; i++) {
@@ -8799,7 +8845,8 @@
// Allocate an instance of the implicit receiver object.
HValue* size_in_bytes =
- AddInstruction(new(zone()) HConstant(instance_size));
+ AddInstruction(new(zone()) HConstant(instance_size,
+ Representation::Integer32()));
HAllocate::Flags flags = HAllocate::DefaultFlags();
if (FLAG_pretenuring_call_new &&
@@ -8817,7 +8864,8 @@
// Load the initial map from the constructor.
HValue* constructor_value =
- AddInstruction(new(zone()) HConstant(constructor));
+ AddInstruction(new(zone()) HConstant(constructor,
+ Representation::Tagged()));
HValue* initial_map_value =
AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset(
JSFunction::kPrototypeOrInitialMapOffset));
@@ -8829,7 +8877,8 @@
HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
initial_map_value);
HValue* empty_fixed_array =
- AddInstruction(new(zone()) HConstant(factory->empty_fixed_array()));
+ AddInstruction(new(zone()) HConstant(factory->empty_fixed_array(),
+ Representation::Tagged()));
AddStore(receiver,
HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
empty_fixed_array);
@@ -9225,11 +9274,10 @@
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
Handle<Map> map;
- HInstruction* load = NULL;
+ HInstruction* load;
bool monomorphic = prop->IsMonomorphic();
- SmallMapList* types = prop->GetReceiverTypes();
if (monomorphic) {
- map = types->first();
+ map = prop->GetReceiverTypes()->first();
if (map->is_dictionary_map()) monomorphic = false;
}
if (monomorphic) {
@@ -9240,10 +9288,9 @@
} else {
load = BuildLoadNamedMonomorphic(object, name, prop, map);
}
- } else if (types != NULL && types->length() > 1) {
- load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
+ } else {
+ load = BuildLoadNamedGeneric(object, name, prop);
}
- if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
PushAndAdd(load);
if (load->HasObservableSideEffects()) {
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
@@ -9331,7 +9378,7 @@
int32_t i = c_index->NumberValueAsInteger32();
Handle<String> s = c_string->StringValue();
if (i < 0 || i >= s->length()) {
- return new(zone()) HConstant(OS::nan_value());
+ return new(zone()) HConstant(OS::nan_value(), Representation::Double());
}
return new(zone()) HConstant(s->Get(i));
}
@@ -9646,7 +9693,6 @@
// TODO(rossberg): this should die eventually.
Representation HOptimizedGraphBuilder::ToRepresentation(TypeInfo info) {
if (info.IsUninitialized()) return Representation::None();
- // TODO(verwaest): Return Smi rather than Integer32.
if (info.IsSmi()) return Representation::Integer32();
if (info.IsInteger32()) return Representation::Integer32();
if (info.IsDouble()) return Representation::Double();
@@ -9880,10 +9926,6 @@
result->set_position(expr->position());
return ast_context()->ReturnInstruction(result, expr->id());
} else {
- // TODO(verwaest): Remove once ToRepresentation properly returns Smi when
- // the IC measures Smi.
- if (left_type->Is(Type::Integer31())) left_rep = Representation::Smi();
- if (right_type->Is(Type::Integer31())) right_rep = Representation::Smi();
HCompareIDAndBranch* result =
new(zone()) HCompareIDAndBranch(left, right, op);
result->set_observed_input_representation(left_rep, right_rep);
@@ -9924,7 +9966,8 @@
// this-function is not a constant, except inside an inlined body.
if (function_state()->outer() != NULL) {
return new(zone()) HConstant(
- function_state()->compilation_info()->closure());
+ function_state()->compilation_info()->closure(),
+ Representation::Tagged());
} else {
return new(zone()) HThisFunction;
}
@@ -9951,7 +9994,9 @@
flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
}
- HValue* size_in_bytes = AddInstruction(new(zone) HConstant(total_size));
+ HValue* size_in_bytes =
+ AddInstruction(new(zone) HConstant(total_size,
+ Representation::Integer32()));
HInstruction* result =
AddInstruction(new(zone) HAllocate(context,
size_in_bytes,
@@ -10008,7 +10053,7 @@
elements_offset += AllocationSiteInfo::kSize;
*offset += AllocationSiteInfo::kSize;
HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant(
- original_boilerplate_object));
+ original_boilerplate_object, Representation::Tagged()));
BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
}
}
@@ -10033,7 +10078,8 @@
if (elements_size == 0) {
Handle<Object> elements_field =
Handle<Object>(boilerplate_object->elements(), isolate());
- elements = AddInstruction(new(zone) HConstant(elements_field));
+ elements = AddInstruction(new(zone) HConstant(
+ elements_field, Representation::Tagged()));
} else {
elements = AddInstruction(new(zone) HInnerAllocatedObject(
target, elements_offset));
@@ -10045,7 +10091,7 @@
Handle<Object>(boilerplate_object->properties(), isolate());
ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
HInstruction* properties = AddInstruction(new(zone) HConstant(
- properties_field));
+ properties_field, Representation::None()));
HObjectAccess access = HObjectAccess::ForPropertiesPointer();
AddStore(object_header, access, properties);
@@ -10054,7 +10100,8 @@
Handle<JSArray>::cast(boilerplate_object);
Handle<Object> length_field =
Handle<Object>(boilerplate_array->length(), isolate());
- HInstruction* length = AddInstruction(new(zone) HConstant(length_field));
+ HInstruction* length = AddInstruction(new(zone) HConstant(
+ length_field, Representation::None()));
ASSERT(boilerplate_array->length()->IsSmi());
Representation representation =
@@ -10110,8 +10157,8 @@
offset, DONT_TRACK_ALLOCATION_SITE);
} else {
Representation representation = details.representation();
- HInstruction* value_instruction =
- AddInstruction(new(zone) HConstant(value));
+ HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
+ value, Representation::Tagged()));
if (representation.IsDouble()) {
// Allocate a HeapNumber box and store the value into it.
@@ -10131,7 +10178,8 @@
int inobject_properties = boilerplate_object->map()->inobject_properties();
HInstruction* value_instruction = AddInstruction(new(zone)
- HConstant(isolate()->factory()->one_pointer_filler_map()));
+ HConstant(isolate()->factory()->one_pointer_filler_map(),
+ Representation::Tagged()));
for (int i = copied_fields; i < inobject_properties; i++) {
ASSERT(boilerplate_object->IsJSObject());
int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
@@ -10173,8 +10221,8 @@
ElementsKind kind,
HValue* object_elements) {
Zone* zone = this->zone();
- HInstruction* boilerplate_elements =
- AddInstruction(new(zone) HConstant(elements));
+ HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
+ elements, Representation::Tagged()));
int elements_length = elements->length();
for (int i = 0; i < elements_length; i++) {
HValue* key_constant = AddInstruction(new(zone) HConstant(i));
@@ -10196,8 +10244,8 @@
HInstruction* target,
int* offset) {
Zone* zone = this->zone();
- HInstruction* boilerplate_elements =
- AddInstruction(new(zone) HConstant(elements));
+ HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
+ elements, Representation::Tagged()));
int elements_length = elements->length();
Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
Handle<FixedArray> original_fast_elements =
@@ -10966,7 +11014,6 @@
values_(arguments, zone),
frame_type_(frame_type),
parameter_count_(arguments),
- specials_count_(0),
local_count_(0),
outer_(outer),
entry_(NULL),
diff --git a/src/hydrogen.h b/src/hydrogen.h
index cefc1bb..a6f0521 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -260,7 +260,6 @@
HStackCheck* stack_check_;
};
-
class BoundsCheckTable;
class HGraph: public ZoneObject {
public:
@@ -412,10 +411,6 @@
depends_on_empty_array_proto_elements_ = true;
}
- bool depends_on_empty_array_proto_elements() {
- return depends_on_empty_array_proto_elements_;
- }
-
void RecordUint32Instruction(HInstruction* instr) {
if (uint32_instructions_ == NULL) {
uint32_instructions_ = new(zone()) ZoneList<HInstruction*>(4, zone());
@@ -881,11 +876,6 @@
HEnterInlined* entry() { return entry_; }
void set_entry(HEnterInlined* entry) { entry_ = entry; }
- HArgumentsObject* arguments_object() { return arguments_object_; }
- void set_arguments_object(HArgumentsObject* arguments_object) {
- arguments_object_ = arguments_object;
- }
-
HArgumentsElements* arguments_elements() { return arguments_elements_; }
void set_arguments_elements(HArgumentsElements* arguments_elements) {
arguments_elements_ = arguments_elements;
@@ -919,7 +909,6 @@
// entry.
HEnterInlined* entry_;
- HArgumentsObject* arguments_object_;
HArgumentsElements* arguments_elements_;
FunctionState* outer_;
@@ -1091,7 +1080,8 @@
HInstruction* IfCompare(
HValue* left,
HValue* right,
- Token::Value token);
+ Token::Value token,
+ Representation input_representation = Representation::Integer32());
HInstruction* IfCompareMap(HValue* left, Handle<Map> map);
@@ -1123,9 +1113,10 @@
HInstruction* OrIfCompare(
HValue* p1,
HValue* p2,
- Token::Value token) {
+ Token::Value token,
+ Representation input_representation = Representation::Integer32()) {
Or();
- return IfCompare(p1, p2, token);
+ return IfCompare(p1, p2, token, input_representation);
}
HInstruction* OrIfCompareMap(HValue* left, Handle<Map> map) {
@@ -1148,9 +1139,10 @@
HInstruction* AndIfCompare(
HValue* p1,
HValue* p2,
- Token::Value token) {
+ Token::Value token,
+ Representation input_representation = Representation::Integer32()) {
And();
- return IfCompare(p1, p2, token);
+ return IfCompare(p1, p2, token, input_representation);
}
HInstruction* AndIfCompareMap(HValue* left, Handle<Map> map) {
@@ -1698,10 +1690,10 @@
HValue* object,
SmallMapList* types,
Handle<String> name);
- HInstruction* TryLoadPolymorphicAsMonomorphic(Property* expr,
- HValue* object,
- SmallMapList* types,
- Handle<String> name);
+ bool HandlePolymorphicArrayLengthLoad(Property* expr,
+ HValue* object,
+ SmallMapList* types,
+ Handle<String> name);
void HandlePolymorphicStoreNamedField(Assignment* expr,
HValue* object,
HValue* value,
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 1e9c330..aa4b8a2 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -7661,11 +7661,11 @@
void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : element value to store
+ // -- ebx : array literal
+ // -- edi : map of array literal
// -- ecx : element index as smi
+ // -- edx : array literal index in function
// -- esp[0] : return address
- // -- esp[4] : array literal index in function
- // -- esp[8] : array literal
- // clobbers ebx, edx, edi
// -----------------------------------
Label element_done;
@@ -7675,11 +7675,6 @@
Label slow_elements_from_double;
Label fast_elements;
- // Get array literal index, array literal and its map.
- __ mov(edx, Operand(esp, 1 * kPointerSize));
- __ mov(ebx, Operand(esp, 2 * kPointerSize));
- __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
-
__ CheckFastElements(edi, &double_elements);
// Check for FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS elements
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 54e9eaf..c4c1e87 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -342,7 +342,7 @@
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
@@ -384,7 +384,7 @@
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -1788,8 +1788,7 @@
}
if (!result_saved) {
- __ push(eax); // array literal.
- __ push(Immediate(Smi::FromInt(expr->literal_index())));
+ __ push(eax);
result_saved = true;
}
VisitForAccumulatorValue(subexpr);
@@ -1798,7 +1797,7 @@
// Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they
// cannot transition and don't need to call the runtime stub.
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
- __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal.
+ __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
__ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
// Store the subexpression value in the array's elements.
__ mov(FieldOperand(ebx, offset), result_register());
@@ -1809,7 +1808,10 @@
INLINE_SMI_CHECK);
} else {
// Store the subexpression value in the array's elements.
+ __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
+ __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
__ mov(ecx, Immediate(Smi::FromInt(i)));
+ __ mov(edx, Immediate(Smi::FromInt(expr->literal_index())));
StoreArrayLiteralElementStub stub;
__ CallStub(&stub);
}
@@ -1818,7 +1820,6 @@
}
if (result_saved) {
- __ add(esp, Immediate(kPointerSize)); // literal index
context()->PlugTOS();
} else {
context()->Plug(eax);
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 2e27097..95c7c02 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -1482,8 +1482,8 @@
}
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
- StrictModeFlag strict_mode) {
+void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
+ StrictModeFlag strict_mode) {
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : name
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index cfda00a..5df6d81 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -614,15 +614,27 @@
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* pushed_arguments_index,
+ int* pushed_arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
- int translation_size = environment->translation_size();
+ int translation_size = environment->values()->length();
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *pushed_arguments_index = -environment->parameter_count();
+ *pushed_arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ pushed_arguments_index,
+ pushed_arguments_count);
bool has_closure_id = !info()->closure().is_null() &&
!info()->closure().is_identical_to(environment->closure());
int closure_id = has_closure_id
@@ -655,6 +667,23 @@
UNREACHABLE();
}
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and another stack area to be used for materialization,
+ // otherwise actual argument values are unknown for inlined frames.
+ bool arguments_known = true;
+ int arguments_index = *pushed_arguments_index;
+ int arguments_count = *pushed_arguments_count;
+ if (environment->entry() != NULL) {
+ arguments_known = environment->entry()->arguments_pushed();
+ arguments_index = arguments_index < 0
+ ? GetStackSlotCount() : arguments_index + arguments_count;
+ arguments_count = environment->entry()->arguments_count() + 1;
+ if (environment->entry()->arguments_pushed()) {
+ *pushed_arguments_index = arguments_index;
+ *pushed_arguments_count = arguments_count;
+ }
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -666,7 +695,10 @@
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -675,36 +707,20 @@
translation,
environment->spilled_double_registers()[value->index()],
false,
- false);
+ false,
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
- // TODO(mstarzinger): Introduce marker operands to indicate that this value
- // is not present and must be reconstructed from the deoptimizer. Currently
- // this is only used for the arguments object.
- if (value == NULL) {
- int arguments_count = environment->values()->length() - translation_size;
- translation->BeginArgumentsObject(arguments_count);
- for (int i = 0; i < arguments_count; ++i) {
- LOperand* value = environment->values()->at(translation_size + i);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsRegister() ||
- environment->spilled_registers()[value->index()] == NULL);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsDoubleRegister() ||
- environment->spilled_double_registers()[value->index()] == NULL);
- AddToTranslation(translation,
- value,
- environment->HasTaggedValueAt(translation_size + i),
- environment->HasUint32ValueAt(translation_size + i));
- }
- continue;
- }
-
AddToTranslation(translation,
value,
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
@@ -712,8 +728,17 @@
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32) {
- if (op->IsStackSlot()) {
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count) {
+ if (op == NULL) {
+ // TODO(twuerthinger): Introduce marker operands to indicate that this value
+ // is not present and must be reconstructed from the deoptimizer. Currently
+ // this is only used for the arguments object.
+ translation->StoreArgumentsObject(
+ arguments_known, arguments_index, arguments_count);
+ } else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
} else if (is_uint32) {
@@ -839,6 +864,8 @@
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
@@ -846,7 +873,7 @@
}
}
Translation translation(&translations_, frame_count, jsframe_count, zone());
- WriteTranslation(environment, &translation);
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index 21f6076..33f0eda 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -168,7 +168,10 @@
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
void EnsureRelocSpaceForDeoptimization();
@@ -282,7 +285,10 @@
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32);
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count);
void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index e85c79c..325ed2c 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -990,7 +990,7 @@
BailoutId ast_id = hydrogen_env->ast_id();
ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
- int value_count = hydrogen_env->length() - hydrogen_env->specials_count();
+ int value_count = hydrogen_env->length();
LEnvironment* result =
new(zone()) LEnvironment(hydrogen_env->closure(),
hydrogen_env->frame_type(),
@@ -1001,15 +1001,13 @@
outer,
hydrogen_env->entry(),
zone());
- bool needs_arguments_object_materialization = false;
int argument_index = *argument_index_accumulator;
- for (int i = 0; i < hydrogen_env->length(); ++i) {
+ for (int i = 0; i < value_count; ++i) {
if (hydrogen_env->is_special_index(i)) continue;
HValue* value = hydrogen_env->values()->at(i);
LOperand* op = NULL;
if (value->IsArgumentsObject()) {
- needs_arguments_object_materialization = true;
op = NULL;
} else if (value->IsPushArgument()) {
op = new(zone()) LArgument(argument_index++);
@@ -1021,21 +1019,6 @@
value->CheckFlag(HInstruction::kUint32));
}
- if (needs_arguments_object_materialization) {
- HArgumentsObject* arguments = hydrogen_env->entry() == NULL
- ? graph()->GetArgumentsObject()
- : hydrogen_env->entry()->arguments_object();
- ASSERT(arguments->IsLinked());
- for (int i = 1; i < arguments->arguments_count(); ++i) {
- HValue* value = arguments->arguments_values()->at(i);
- ASSERT(!value->IsArgumentsObject() && !value->IsPushArgument());
- LOperand* op = UseAny(value);
- result->AddValue(op,
- value->representation(),
- value->CheckFlag(HInstruction::kUint32));
- }
- }
-
if (hydrogen_env->frame_type() == JS_FUNCTION) {
*argument_index_accumulator = argument_index;
}
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 17d4aac..60c5c26 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1973,8 +1973,6 @@
void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
- Address thunk_address,
- Operand thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset) {
@@ -2000,26 +1998,8 @@
PopSafepointRegisters();
}
-
- Label profiler_disabled;
- Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- mov(eax, Immediate(reinterpret_cast<Address>(is_profiling_flag)));
- cmpb(Operand(eax, 0), 0);
- j(zero, &profiler_disabled);
-
- // Additional parameter is the address of the actual getter function.
- mov(thunk_last_arg, Immediate(function_address));
- // Call the api function.
- call(thunk_address, RelocInfo::RUNTIME_ENTRY);
- jmp(&end_profiler_check);
-
- bind(&profiler_disabled);
// Call the api function.
call(function_address, RelocInfo::RUNTIME_ENTRY);
- bind(&end_profiler_check);
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 7d780f0..8380507 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -784,8 +784,6 @@
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
void CallApiFunctionAndReturn(Address function_address,
- Address thunk_address,
- Operand thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_ebp);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 38578c7..93923a7 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -503,12 +503,7 @@
STATIC_ASSERT(kFastApiCallArguments == 6);
__ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
-
- // API function gets reference to the v8::Arguments. If CPU profiler
- // is enabled wrapper function will be called and we need to pass
- // address of the callback as additional parameter, always allocate
- // space for it.
- const int kApiArgc = 1 + 1;
+ const int kApiArgc = 1; // API function gets reference to the v8::Arguments.
// Allocate the v8::Arguments structure in the arguments' space since
// it's not controlled by GC.
@@ -522,26 +517,20 @@
__ PrepareCallApiFunction(kApiArgc + kApiStackSpace, returns_handle);
// v8::Arguments::implicit_args_.
- __ mov(ApiParameterOperand(2, returns_handle), eax);
+ __ mov(ApiParameterOperand(1, returns_handle), eax);
__ add(eax, Immediate(argc * kPointerSize));
// v8::Arguments::values_.
- __ mov(ApiParameterOperand(3, returns_handle), eax);
+ __ mov(ApiParameterOperand(2, returns_handle), eax);
// v8::Arguments::length_.
- __ Set(ApiParameterOperand(4, returns_handle), Immediate(argc));
+ __ Set(ApiParameterOperand(3, returns_handle), Immediate(argc));
// v8::Arguments::is_construct_call_.
- __ Set(ApiParameterOperand(5, returns_handle), Immediate(0));
+ __ Set(ApiParameterOperand(4, returns_handle), Immediate(0));
// v8::InvocationCallback's argument.
- __ lea(eax, ApiParameterOperand(2, returns_handle));
+ __ lea(eax, ApiParameterOperand(1, returns_handle));
__ mov(ApiParameterOperand(0, returns_handle), eax);
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
-
__ CallApiFunctionAndReturn(function_address,
- thunk_address,
- ApiParameterOperand(1, returns_handle),
argc + kFastApiCallArguments + 1,
returns_handle,
kFastApiCallArguments + 1);
@@ -850,14 +839,8 @@
Register storage_reg = name_reg;
- if (details.type() == CONSTANT_FUNCTION) {
- Handle<HeapObject> constant(
- HeapObject::cast(descriptors->GetValue(descriptor)));
- __ LoadHeapObject(scratch1, constant);
- __ cmp(value_reg, scratch1);
- __ j(not_equal, miss_restore_name);
- } else if (FLAG_track_fields && representation.IsSmi()) {
- __ JumpIfNotSmi(value_reg, miss_restore_name);
+ if (FLAG_track_fields && representation.IsSmi()) {
+ __ JumpIfNotSmi(value_reg, miss_restore_name);
} else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_restore_name);
} else if (FLAG_track_double_fields && representation.IsDouble()) {
@@ -901,8 +884,7 @@
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Perform map transition for the receiver if necessary.
- if (details.type() == FIELD &&
- object->map()->unused_property_fields() == 0) {
+ 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 properties array.
__ pop(scratch1); // Return address.
@@ -931,8 +913,6 @@
OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
- if (details.type() == CONSTANT_FUNCTION) return;
-
int index = transition->instance_descriptors()->GetFieldIndex(
transition->LastAdded());
@@ -1426,9 +1406,7 @@
// array for v8::Arguments::values_, handler for name and pointer
// to the values (it considered as smi in GC).
const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2;
- // Allocate space for opional callback address parameter in case
- // CPU profiler is active.
- const int kApiArgc = 2 + 1;
+ const int kApiArgc = 2;
Address getter_address = v8::ToCData<Address>(callback->getter());
bool returns_handle =
@@ -1444,13 +1422,7 @@
// garbage collection but instead return the allocation failure
// object.
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
-
__ CallApiFunctionAndReturn(getter_address,
- thunk_address,
- ApiParameterOperand(2, returns_handle),
kStackSpace,
returns_handle,
6);
diff --git a/src/ic.cc b/src/ic.cc
index 029aafd..095b614 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -936,7 +936,15 @@
}
// Update inline cache and stub cache.
- if (FLAG_use_ic) UpdateCaches(&lookup, state, object, name);
+ if (FLAG_use_ic) {
+ if (!object->IsJSObject()) {
+ // TODO(jkummerow): It would be nice to support non-JSObjects in
+ // UpdateCaches, then we wouldn't need to go generic here.
+ set_target(*generic_stub());
+ } else {
+ UpdateCaches(&lookup, state, object, name);
+ }
+ }
PropertyAttributes attr;
if (lookup.IsInterceptor() || lookup.IsHandler()) {
@@ -1196,17 +1204,11 @@
Handle<Object> object,
Handle<String> name) {
// Bail out if the result is not cacheable.
- if (!lookup->IsCacheable()) {
- set_target(*generic_stub());
- return;
- }
+ if (!lookup->IsCacheable()) return;
- // TODO(jkummerow): It would be nice to support non-JSObjects in
- // UpdateCaches, then we wouldn't need to go generic here.
- if (!object->IsJSObject()) {
- set_target(*generic_stub());
- return;
- }
+ // Loading properties from values is not common, so don't try to
+ // deal with non-JS objects here.
+ if (!object->IsJSObject()) return;
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
Handle<Code> code;
@@ -1217,10 +1219,7 @@
code = pre_monomorphic_stub();
} else {
code = ComputeLoadHandler(lookup, receiver, name);
- if (code.is_null()) {
- set_target(*generic_stub());
- return;
- }
+ if (code.is_null()) return;
}
PatchCache(state, kNonStrictMode, receiver, name, code);
@@ -1641,12 +1640,6 @@
IsUndeclaredGlobal(object)) {
// Strict mode doesn't allow setting non-existent global property.
return ReferenceError("not_defined", name);
- } else if (FLAG_use_ic &&
- (lookup.IsNormal() ||
- (lookup.IsField() && lookup.CanHoldValue(value)))) {
- Handle<Code> stub = strict_mode == kStrictMode
- ? generic_stub_strict() : generic_stub();
- set_target(*stub);
}
// Set the property.
@@ -1667,14 +1660,9 @@
// These are not cacheable, so we never see such LookupResults here.
ASSERT(!lookup->IsHandler());
- Handle<Code> code = ComputeStoreMonomorphic(
- lookup, strict_mode, receiver, name);
- if (code.is_null()) {
- Handle<Code> stub = strict_mode == kStrictMode
- ? generic_stub_strict() : generic_stub();
- set_target(*stub);
- return;
- }
+ Handle<Code> code =
+ ComputeStoreMonomorphic(lookup, strict_mode, receiver, name);
+ if (code.is_null()) return;
PatchCache(state, strict_mode, receiver, name, code);
TRACE_IC("StoreIC", name, state, target());
@@ -1745,7 +1733,7 @@
DescriptorArray* target_descriptors = transition->instance_descriptors();
PropertyDetails details = target_descriptors->GetDetails(descriptor);
- if (details.type() == CALLBACKS || details.attributes() != NONE) break;
+ if (details.type() != FIELD || details.attributes() != NONE) break;
return isolate()->stub_cache()->ComputeStoreTransition(
name, receiver, lookup, transition, strict_mode);
@@ -2111,7 +2099,7 @@
DescriptorArray* target_descriptors = transition->instance_descriptors();
PropertyDetails details = target_descriptors->GetDetails(descriptor);
- if (details.type() != CALLBACKS && details.attributes() == NONE) {
+ if (details.type() == FIELD && details.attributes() == NONE) {
return isolate()->stub_cache()->ComputeKeyedStoreTransition(
name, receiver, lookup, transition, strict_mode);
}
diff --git a/src/ic.h b/src/ic.h
index e6e8817..fc869ad 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -511,8 +511,8 @@
static void GenerateMegamorphic(MacroAssembler* masm,
StrictModeFlag strict_mode);
static void GenerateNormal(MacroAssembler* masm);
- static void GenerateRuntimeSetProperty(MacroAssembler* masm,
- StrictModeFlag strict_mode);
+ static void GenerateGlobalProxy(MacroAssembler* masm,
+ StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* Store(
State state,
@@ -532,12 +532,6 @@
virtual Handle<Code> megamorphic_stub_strict() {
return isolate()->builtins()->StoreIC_Megamorphic_Strict();
}
- virtual Handle<Code> generic_stub() const {
- return isolate()->builtins()->StoreIC_Generic();
- }
- virtual Handle<Code> generic_stub_strict() const {
- return isolate()->builtins()->StoreIC_Generic_Strict();
- }
virtual Handle<Code> global_proxy_stub() {
return isolate()->builtins()->StoreIC_GlobalProxy();
}
diff --git a/src/lithium.h b/src/lithium.h
index ab34453..170e5c8 100644
--- a/src/lithium.h
+++ b/src/lithium.h
@@ -527,7 +527,6 @@
deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
translation_index_(-1),
ast_id_(ast_id),
- translation_size_(value_count),
parameter_count_(parameter_count),
pc_offset_(-1),
values_(value_count, zone),
@@ -545,7 +544,6 @@
int deoptimization_index() const { return deoptimization_index_; }
int translation_index() const { return translation_index_; }
BailoutId ast_id() const { return ast_id_; }
- int translation_size() const { return translation_size_; }
int parameter_count() const { return parameter_count_; }
int pc_offset() const { return pc_offset_; }
LOperand** spilled_registers() const { return spilled_registers_; }
@@ -555,7 +553,6 @@
const ZoneList<LOperand*>* values() const { return &values_; }
LEnvironment* outer() const { return outer_; }
HEnterInlined* entry() { return entry_; }
- Zone* zone() const { return zone_; }
void AddValue(LOperand* operand,
Representation representation,
@@ -563,11 +560,11 @@
values_.Add(operand, zone());
if (representation.IsSmiOrTagged()) {
ASSERT(!is_uint32);
- is_tagged_.Add(values_.length() - 1, zone());
+ is_tagged_.Add(values_.length() - 1);
}
if (is_uint32) {
- is_uint32_.Add(values_.length() - 1, zone());
+ is_uint32_.Add(values_.length() - 1);
}
}
@@ -599,6 +596,8 @@
void PrintTo(StringStream* stream);
+ Zone* zone() const { return zone_; }
+
private:
Handle<JSFunction> closure_;
FrameType frame_type_;
@@ -606,15 +605,11 @@
int deoptimization_index_;
int translation_index_;
BailoutId ast_id_;
- int translation_size_;
int parameter_count_;
int pc_offset_;
-
- // Value array: [parameters] [locals] [expression stack] [de-materialized].
- // |>--------- translation_size ---------<|
ZoneList<LOperand*> values_;
- GrowableBitVector is_tagged_;
- GrowableBitVector is_uint32_;
+ BitVector is_tagged_;
+ BitVector is_uint32_;
// Allocation index indexed arrays of spill slot operands for registers
// that are also in spill slots at an OSR entry. NULL for environments
@@ -624,6 +619,7 @@
LEnvironment* outer_;
HEnterInlined* entry_;
+
Zone* zone_;
};
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index d319aa2..0501ccf 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1495,13 +1495,15 @@
FIXED_ARRAY_TYPE) return;
// Make sure this is a RegExp that actually contains code.
- if (re->TypeTag() != JSRegExp::IRREGEXP) return;
+ if (re->TypeTagUnchecked() != JSRegExp::IRREGEXP) return;
- Object* code = re->DataAt(JSRegExp::code_index(is_ascii));
+ Object* code = re->DataAtUnchecked(JSRegExp::code_index(is_ascii));
if (!code->IsSmi() &&
HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) {
// Save a copy that can be reinstated if we need the code again.
- re->SetDataAt(JSRegExp::saved_code_index(is_ascii), code);
+ re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii),
+ code,
+ heap);
// Saving a copy might create a pointer into compaction candidate
// that was not observed by marker. This might happen if JSRegExp data
@@ -1513,8 +1515,9 @@
RecordSlot(slot, slot, code);
// Set a number in the 0-255 range to guarantee no smi overflow.
- re->SetDataAt(JSRegExp::code_index(is_ascii),
- Smi::FromInt(heap->sweep_generation() & 0xff));
+ re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii),
+ Smi::FromInt(heap->sweep_generation() & 0xff),
+ heap);
} else if (code->IsSmi()) {
int value = Smi::cast(code)->value();
// The regexp has not been compiled yet or there was a compilation error.
@@ -1525,10 +1528,12 @@
// Check if we should flush now.
if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) {
- re->SetDataAt(JSRegExp::code_index(is_ascii),
- Smi::FromInt(JSRegExp::kUninitializedValue));
- re->SetDataAt(JSRegExp::saved_code_index(is_ascii),
- Smi::FromInt(JSRegExp::kUninitializedValue));
+ re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii),
+ Smi::FromInt(JSRegExp::kUninitializedValue),
+ heap);
+ re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii),
+ Smi::FromInt(JSRegExp::kUninitializedValue),
+ heap);
}
}
}
@@ -2443,7 +2448,7 @@
// This map is used for inobject slack tracking and has been detached
// from SharedFunctionInfo during the mark phase.
// Since it survived the GC, reattach it now.
- JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map);
+ map->unchecked_constructor()->shared()->AttachInitialMap(map);
}
ClearNonLivePrototypeTransitions(map);
@@ -2474,11 +2479,13 @@
int proto_index = proto_offset + new_number_of_transitions * step;
int map_index = map_offset + new_number_of_transitions * step;
if (new_number_of_transitions != i) {
- prototype_transitions->set(
+ prototype_transitions->set_unchecked(
+ heap_,
proto_index,
prototype,
UPDATE_WRITE_BARRIER);
- prototype_transitions->set(
+ prototype_transitions->set_unchecked(
+ heap_,
map_index,
cached_map,
SKIP_WRITE_BARRIER);
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index f09e9c3..5c8d08c 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -2488,36 +2488,47 @@
UNREACHABLE();
}
- if (result_type_ <= BinaryOpIC::INT32) {
+ if (op_ != Token::DIV) {
+ // These operations produce an integer result.
+ // Try to return a smi if we can.
+ // Otherwise return a heap number if allowed, or jump to type
+ // transition.
+
Register except_flag = scratch2;
- const FPURoundingMode kRoundingMode = op_ == Token::DIV ?
- kRoundToMinusInf : kRoundToZero;
- const CheckForInexactConversion kConversion = op_ == Token::DIV ?
- kCheckForInexactConversion : kDontCheckForInexactConversion;
- __ EmitFPUTruncate(kRoundingMode,
+ __ EmitFPUTruncate(kRoundToZero,
scratch1,
f10,
at,
f16,
- except_flag,
- kConversion);
- // If except_flag != 0, result does not fit in a 32-bit integer.
- __ Branch(&transition, ne, except_flag, Operand(zero_reg));
- // Try to tag the result as a Smi, return heap number on overflow.
- __ SmiTagCheckOverflow(scratch1, scratch1, scratch2);
+ except_flag);
+
+ if (result_type_ <= BinaryOpIC::INT32) {
+ // If except_flag != 0, result does not fit in a 32-bit integer.
+ __ Branch(&transition, ne, except_flag, Operand(zero_reg));
+ }
+
+ // Check if the result fits in a smi.
+ __ Addu(scratch2, scratch1, Operand(0x40000000));
+ // If not try to return a heap number.
__ Branch(&return_heap_number, lt, scratch2, Operand(zero_reg));
- // Check for minus zero, transition in that case (because we need
- // to return a heap number).
+ // Check for minus zero. Return heap number for minus zero if
+ // double results are allowed; otherwise transition.
Label not_zero;
- ASSERT(kSmiTag == 0);
__ Branch(¬_zero, ne, scratch1, Operand(zero_reg));
__ mfc1(scratch2, f11);
__ And(scratch2, scratch2, HeapNumber::kSignMask);
- __ Branch(&transition, ne, scratch2, Operand(zero_reg));
+ __ Branch(result_type_ <= BinaryOpIC::INT32 ? &transition
+ : &return_heap_number,
+ ne,
+ scratch2,
+ Operand(zero_reg));
__ bind(¬_zero);
+ // Tag the result and return.
__ Ret(USE_DELAY_SLOT);
- __ mov(v0, scratch1);
+ __ SmiTag(v0, scratch1); // SmiTag emits one instruction.
+ } else {
+ // DIV just falls through to allocating a heap number.
}
__ bind(&return_heap_number);
@@ -6901,6 +6912,13 @@
void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
+ ExternalReference function) {
+ __ li(t9, Operand(function));
+ this->GenerateCall(masm, t9);
+}
+
+
+void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
Register target) {
__ Move(t9, target);
__ AssertStackIsAligned();
@@ -7482,10 +7500,10 @@
void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : element value to store
+ // -- a1 : array literal
+ // -- a2 : map of array literal
// -- a3 : element index as smi
- // -- sp[0] : array literal index in function as smi
- // -- sp[4] : array literal
- // clobbers a1, a2, t0
+ // -- t0 : array literal index in function as smi
// -----------------------------------
Label element_done;
@@ -7494,11 +7512,6 @@
Label slow_elements;
Label fast_elements;
- // Get array literal index, array literal and its map.
- __ lw(t0, MemOperand(sp, 0 * kPointerSize));
- __ lw(a1, MemOperand(sp, 1 * kPointerSize));
- __ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset));
-
__ CheckFastElements(a2, t1, &double_elements);
// Check for FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS elements
__ JumpIfSmi(a0, &smi_element);
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index bf5db10..ec7d147 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -599,6 +599,8 @@
public:
DirectCEntryStub() {}
void Generate(MacroAssembler* masm);
+ void GenerateCall(MacroAssembler* masm,
+ ExternalReference function);
void GenerateCall(MacroAssembler* masm, Register target);
private:
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index df83019..a16e478 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -363,7 +363,7 @@
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ slt(at, a3, zero_reg);
@@ -406,7 +406,7 @@
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -1840,8 +1840,7 @@
}
if (!result_saved) {
- __ push(v0); // array literal
- __ Push(Smi::FromInt(expr->literal_index()));
+ __ push(v0);
result_saved = true;
}
@@ -1849,7 +1848,7 @@
if (IsFastObjectElementsKind(constant_elements_kind)) {
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
- __ lw(t2, MemOperand(sp, kPointerSize)); // Copy of array literal.
+ __ lw(t2, MemOperand(sp)); // Copy of array literal.
__ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset));
__ sw(result_register(), FieldMemOperand(a1, offset));
// Update the write barrier for the array store.
@@ -1857,7 +1856,10 @@
kRAHasBeenSaved, kDontSaveFPRegs,
EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
} else {
+ __ lw(a1, MemOperand(sp)); // Copy of array literal.
+ __ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset));
__ li(a3, Operand(Smi::FromInt(i)));
+ __ li(t0, Operand(Smi::FromInt(expr->literal_index())));
__ mov(a0, result_register());
StoreArrayLiteralElementStub stub;
__ CallStub(&stub);
@@ -1866,7 +1868,6 @@
PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
}
if (result_saved) {
- __ Pop(); // literal index
context()->PlugTOS();
} else {
context()->Plug(v0);
@@ -2041,21 +2042,23 @@
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Branch(&l_next);
- // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
+ // catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; }
__ 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(a3); // iter
__ push(a0); // exception
+ __ mov(a0, a3); // iter
+ __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
+ Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize();
+ CallIC(throw_ic); // iter.throw in a0
+ __ mov(a0, v0);
__ jmp(&l_call);
- // try { received = %yield result }
- // Shuffle the received result above a try handler and yield it without
- // re-boxing.
+ // try { received = yield result.value }
__ bind(&l_try);
- __ pop(a0); // result
+ EmitCreateIteratorResult(false); // pop and box to v0
__ PushTryHandler(StackHandler::CATCH, expr->index());
const int handler_size = StackHandlerConstants::kSize;
__ push(a0); // result
@@ -2073,23 +2076,45 @@
__ bind(&l_resume); // received in a0
__ PopTryHandler();
- // receiver = iter; f = 'next'; arg = received;
+ // receiver = iter; f = iter.next; arg = received;
__ bind(&l_next);
- __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
__ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ push(a3); // iter
__ push(a0); // received
+ __ mov(a0, a3); // iter
+ __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
+ Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
+ CallIC(next_ic); // iter.next in a0
+ __ mov(a0, v0);
- // result = receiver[f](arg);
+ // result = f.call(receiver, arg);
__ bind(&l_call);
- Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
- CallIC(ic);
+ Label l_call_runtime;
+ __ JumpIfSmi(a0, &l_call_runtime);
+ __ GetObjectType(a0, a1, a1);
+ __ Branch(&l_call_runtime, ne, a1, Operand(JS_FUNCTION_TYPE));
+ __ mov(a1, a0);
+ ParameterCount count(1);
+ __ InvokeFunction(a1, count, CALL_FUNCTION,
+ NullCallWrapper(), CALL_AS_METHOD);
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ __ jmp(&l_loop);
+ __ bind(&l_call_runtime);
+ __ push(a0);
+ __ CallRuntime(Runtime::kCall, 3);
- // if (!result.done) goto l_try;
+ // val = result.value; if (!result.done) goto l_try;
__ bind(&l_loop);
__ mov(a0, v0);
+ // result.value
__ push(a0); // save result
+ __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value"
+ Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
+ CallIC(value_ic); // result.value in a0
+ __ mov(a0, v0);
+ __ pop(a1); // result
+ __ push(a0); // result.value
+ __ mov(a0, a1); // result
__ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done"
Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize();
CallIC(done_ic); // result.done in v0
@@ -2099,10 +2124,7 @@
__ Branch(&l_try, eq, v0, Operand(zero_reg));
// result.value
- __ pop(a0); // result
- __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value"
- Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
- CallIC(value_ic); // result.value in v0
+ __ pop(v0); // result.value
context()->DropAndPlug(2, v0); // drop iter and g
break;
}
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index b30ee31..c1b4e1e 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -1588,8 +1588,8 @@
}
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
- StrictModeFlag strict_mode) {
+void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
+ StrictModeFlag strict_mode) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 0f02578..c256646 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -561,15 +561,27 @@
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* pushed_arguments_index,
+ int* pushed_arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
- int translation_size = environment->translation_size();
+ int translation_size = environment->values()->length();
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *pushed_arguments_index = -environment->parameter_count();
+ *pushed_arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ pushed_arguments_index,
+ pushed_arguments_count);
bool has_closure_id = !info()->closure().is_null() &&
!info()->closure().is_identical_to(environment->closure());
int closure_id = has_closure_id
@@ -601,6 +613,23 @@
break;
}
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and another stack area to be used for materialization,
+ // otherwise actual argument values are unknown for inlined frames.
+ bool arguments_known = true;
+ int arguments_index = *pushed_arguments_index;
+ int arguments_count = *pushed_arguments_count;
+ if (environment->entry() != NULL) {
+ arguments_known = environment->entry()->arguments_pushed();
+ arguments_index = arguments_index < 0
+ ? GetStackSlotCount() : arguments_index + arguments_count;
+ arguments_count = environment->entry()->arguments_count() + 1;
+ if (environment->entry()->arguments_pushed()) {
+ *pushed_arguments_index = arguments_index;
+ *pushed_arguments_count = arguments_count;
+ }
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -612,7 +641,10 @@
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -621,36 +653,20 @@
translation,
environment->spilled_double_registers()[value->index()],
false,
- false);
+ false,
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
- // TODO(mstarzinger): Introduce marker operands to indicate that this value
- // is not present and must be reconstructed from the deoptimizer. Currently
- // this is only used for the arguments object.
- if (value == NULL) {
- int arguments_count = environment->values()->length() - translation_size;
- translation->BeginArgumentsObject(arguments_count);
- for (int i = 0; i < arguments_count; ++i) {
- LOperand* value = environment->values()->at(translation_size + i);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsRegister() ||
- environment->spilled_registers()[value->index()] == NULL);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsDoubleRegister() ||
- environment->spilled_double_registers()[value->index()] == NULL);
- AddToTranslation(translation,
- value,
- environment->HasTaggedValueAt(translation_size + i),
- environment->HasUint32ValueAt(translation_size + i));
- }
- continue;
- }
-
AddToTranslation(translation,
value,
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
@@ -658,8 +674,17 @@
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32) {
- if (op->IsStackSlot()) {
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count) {
+ if (op == NULL) {
+ // TODO(twuerthinger): Introduce marker operands to indicate that this value
+ // is not present and must be reconstructed from the deoptimizer. Currently
+ // this is only used for the arguments object.
+ translation->StoreArgumentsObject(
+ arguments_known, arguments_index, arguments_count);
+ } else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
} else if (is_uint32) {
@@ -754,6 +779,8 @@
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
@@ -761,7 +788,7 @@
}
}
Translation translation(&translations_, frame_count, jsframe_count, zone());
- WriteTranslation(environment, &translation);
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index a8d7e04..ee01383 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -169,7 +169,10 @@
int additional_offset);
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) void Do##type(L##type* node);
@@ -292,7 +295,10 @@
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32);
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count);
void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index d4f450e..ad39c61 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -933,7 +933,7 @@
BailoutId ast_id = hydrogen_env->ast_id();
ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
- int value_count = hydrogen_env->length() - hydrogen_env->specials_count();
+ int value_count = hydrogen_env->length();
LEnvironment* result = new(zone()) LEnvironment(
hydrogen_env->closure(),
hydrogen_env->frame_type(),
@@ -944,15 +944,13 @@
outer,
hydrogen_env->entry(),
zone());
- bool needs_arguments_object_materialization = false;
int argument_index = *argument_index_accumulator;
- for (int i = 0; i < hydrogen_env->length(); ++i) {
+ for (int i = 0; i < value_count; ++i) {
if (hydrogen_env->is_special_index(i)) continue;
HValue* value = hydrogen_env->values()->at(i);
LOperand* op = NULL;
if (value->IsArgumentsObject()) {
- needs_arguments_object_materialization = true;
op = NULL;
} else if (value->IsPushArgument()) {
op = new(zone()) LArgument(argument_index++);
@@ -964,21 +962,6 @@
value->CheckFlag(HInstruction::kUint32));
}
- if (needs_arguments_object_materialization) {
- HArgumentsObject* arguments = hydrogen_env->entry() == NULL
- ? graph()->GetArgumentsObject()
- : hydrogen_env->entry()->arguments_object();
- ASSERT(arguments->IsLinked());
- for (int i = 1; i < arguments->arguments_count(); ++i) {
- HValue* value = arguments->arguments_values()->at(i);
- ASSERT(!value->IsArgumentsObject() && !value->IsPushArgument());
- LOperand* op = UseAny(value);
- result->AddValue(op,
- value->representation(),
- value->CheckFlag(HInstruction::kUint32));
- }
- }
-
if (hydrogen_env->frame_type() == JS_FUNCTION) {
*argument_index_accumulator = argument_index;
}
@@ -1359,10 +1342,15 @@
if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::DIV, instr);
} else if (instr->representation().IsInteger32()) {
- LOperand* dividend = UseRegister(instr->left());
- LOperand* divisor = UseRegister(instr->right());
- LDivI* div = new(zone()) LDivI(dividend, divisor);
- return AssignEnvironment(DefineAsRegister(div));
+ // TODO(1042) The fixed register allocation
+ // is needed because we call TypeRecordingBinaryOpStub from
+ // the generated code, which requires registers a0
+ // and a1 to be used. We should remove that
+ // when we provide a native implementation.
+ LOperand* dividend = UseFixed(instr->left(), a0);
+ LOperand* divisor = UseFixed(instr->right(), a1);
+ return AssignEnvironment(AssignPointerMap(
+ DefineFixed(new(zone()) LDivI(dividend, divisor), v0)));
} else {
return DoArithmeticT(Token::DIV, instr);
}
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index d41ddd2..15436e7 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -3909,9 +3909,6 @@
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
- Address function_address,
- ExternalReference thunk_ref,
- Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp) {
@@ -3950,30 +3947,11 @@
addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
}
- Label profiler_disabled;
- Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- li(t9, reinterpret_cast<int32_t>(is_profiling_flag));
- lb(t9, MemOperand(t9, 0));
- beq(t9, zero_reg, &profiler_disabled);
-
- // Third parameter is the address of the actual getter function.
- li(thunk_last_arg, reinterpret_cast<int32_t>(function_address));
- li(t9, Operand(thunk_ref));
- jmp(&end_profiler_check);
-
- bind(&profiler_disabled);
- li(t9, Operand(function));
-
- bind(&end_profiler_check);
-
// Native call returns to the DirectCEntry stub which redirects to the
// return address pushed on stack (could have moved after GC).
// DirectCEntry stub itself is generated early and never moves.
DirectCEntryStub stub;
- stub.GenerateCall(this, t9);
+ stub.GenerateCall(this, function);
if (FLAG_log_timer_events) {
FrameScope frame(this, StackFrame::MANUAL);
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index c983b8b..5e6bfba 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1235,9 +1235,6 @@
// - space to be unwound on exit (includes the call JS arguments space and
// the additional space allocated for the fast call).
void CallApiFunctionAndReturn(ExternalReference function,
- Address function_address,
- ExternalReference thunk_ref,
- Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_fp);
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 8771bd2..d8a39ab 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1394,9 +1394,6 @@
// Here, we pass the first argument in a0, because this function
// does not return a struct.
typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
- int32_t arg0, int32_t arg1);
-typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback.
// See comment at SimulatorRuntimeDirectApiCall.
@@ -1405,10 +1402,6 @@
// See comment at SimulatorRuntimeDirectApiCallNew.
typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
int32_t arg1);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
- int32_t arg0, int32_t arg1, int32_t arg2);
-typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
- int32_t arg0, int32_t arg1, int32_t arg2);
// Software interrupt instructions are used by the simulator to call into the
// C-based V8 runtime. They are also used for debugging with simulator.
@@ -1578,30 +1571,6 @@
target(arg0);
}
} else if (
- redirection->type() == ExternalReference::PROFILING_API_CALL ||
- redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
- if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
- // See comment at type definition of SimulatorRuntimeDirectApiCall
- // for explanation of register usage.
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x\n",
- reinterpret_cast<void*>(external), arg1, arg2);
- }
- SimulatorRuntimeProfilingApiCall target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
- v8::Handle<v8::Value> result = target(arg1, arg2);
- *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
- set_register(v0, arg0);
- } else {
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x\n",
- reinterpret_cast<void*>(external), arg0, arg1);
- }
- SimulatorRuntimeProfilingApiCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
- target(arg0, arg1);
- }
- } else if (
redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
@@ -1625,30 +1594,6 @@
reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
target(arg0, arg1);
}
- } else if (
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
- if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
- // See comment at type definition of SimulatorRuntimeProfilingGetterCall
- // for explanation of register usage.
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x %08x\n",
- reinterpret_cast<void*>(external), arg1, arg2, arg3);
- }
- SimulatorRuntimeProfilingGetterCall target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
- v8::Handle<v8::Value> result = target(arg1, arg2, arg3);
- *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
- set_register(v0, arg0);
- } else {
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x %08x\n",
- reinterpret_cast<void*>(external), arg0, arg1, arg2);
- }
- SimulatorRuntimeProfilingGetterCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(external);
- target(arg0, arg1, arg2);
- }
} else {
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 61f4972..6e42242 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -503,12 +503,7 @@
Register storage_reg = name_reg;
- if (details.type() == CONSTANT_FUNCTION) {
- Handle<HeapObject> constant(
- HeapObject::cast(descriptors->GetValue(descriptor)));
- __ LoadHeapObject(scratch1, constant);
- __ Branch(miss_restore_name, ne, value_reg, Operand(scratch1));
- } else if (FLAG_track_fields && representation.IsSmi()) {
+ if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_restore_name);
} else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_restore_name);
@@ -537,8 +532,7 @@
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Perform map transition for the receiver if necessary.
- if (details.type() == FIELD &&
- object->map()->unused_property_fields() == 0) {
+ 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 properties array.
__ push(receiver_reg);
@@ -566,8 +560,6 @@
OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
- if (details.type() == CONSTANT_FUNCTION) return;
-
int index = transition->instance_descriptors()->GetFieldIndex(
transition->LastAdded());
@@ -940,7 +932,6 @@
!CallbackTable::ReturnsVoid(masm->isolate(), function_address);
Register first_arg = returns_handle ? a1 : a0;
- Register second_arg = returns_handle ? a2 : a1;
// first_arg = v8::Arguments&
// Arguments is built at sp + 1 (sp is a reserved spot for ra).
@@ -967,23 +958,8 @@
ExternalReference(&fun,
type,
masm->isolate());
-
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_API_CALL :
- ExternalReference::PROFILING_API_CALL_NEW;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- masm->isolate());
-
AllowExternalCallThatCantCauseGC scope(masm);
__ CallApiFunctionAndReturn(ref,
- function_address,
- thunk_ref,
- second_arg,
kStackUnwindSpace,
returns_handle,
kFastApiCallArguments + 1);
@@ -1476,7 +1452,6 @@
Register first_arg = returns_handle ? a1 : a0;
Register second_arg = returns_handle ? a2 : a1;
- Register third_arg = returns_handle ? a3 : a2;
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
__ mov(first_arg, sp); // (first argument - see note below) = Handle<Name>
@@ -1497,28 +1472,14 @@
__ Addu(second_arg, sp, kPointerSize);
const int kStackUnwindSpace = kFastApiCallArguments + 1;
-
ApiFunction fun(getter_address);
ExternalReference::Type type =
returns_handle ?
ExternalReference::DIRECT_GETTER_CALL :
ExternalReference::DIRECT_GETTER_CALL_NEW;
- ExternalReference ref = ExternalReference(&fun, type, isolate());
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
- ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_GETTER_CALL :
- ExternalReference::PROFILING_GETTER_CALL_NEW;
- ApiFunction thunk_fun(thunk_address);
- ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
- isolate());
+ ExternalReference ref = ExternalReference(&fun, type, isolate());
__ CallApiFunctionAndReturn(ref,
- getter_address,
- thunk_ref,
- third_arg,
kStackUnwindSpace,
returns_handle,
5);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 47d119a..24af123 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2091,6 +2091,30 @@
}
+void FixedArray::set_unchecked(int index, Smi* value) {
+ ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
+ int offset = kHeaderSize + index * kPointerSize;
+ WRITE_FIELD(this, offset, value);
+}
+
+
+void FixedArray::set_unchecked(Heap* heap,
+ int index,
+ Object* value,
+ WriteBarrierMode mode) {
+ int offset = kHeaderSize + index * kPointerSize;
+ WRITE_FIELD(this, offset, value);
+ CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
+}
+
+
+void FixedArray::set_null_unchecked(Heap* heap, int index) {
+ ASSERT(index >= 0 && index < this->length());
+ ASSERT(!heap->InNewSpace(heap->null_value()));
+ WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
+}
+
+
double* FixedDoubleArray::data_start() {
return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
}
@@ -3553,6 +3577,11 @@
}
+JSFunction* Map::unchecked_constructor() {
+ return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
+}
+
+
Code::Flags Code::flags() {
return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
}
@@ -4715,6 +4744,11 @@
}
+Code* SharedFunctionInfo::unchecked_code() {
+ return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
+}
+
+
void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kCodeOffset, value);
CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
@@ -5251,6 +5285,12 @@
}
+FixedArray* Code::unchecked_deoptimization_data() {
+ return reinterpret_cast<FixedArray*>(
+ READ_FIELD(this, kDeoptimizationDataOffset));
+}
+
+
ByteArray* Code::unchecked_relocation_info() {
return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
}
@@ -5326,6 +5366,12 @@
}
+JSRegExp::Type JSRegExp::TypeTagUnchecked() {
+ Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
+ return static_cast<JSRegExp::Type>(smi->value());
+}
+
+
int JSRegExp::CaptureCount() {
switch (TypeTag()) {
case ATOM:
@@ -5361,6 +5407,13 @@
}
+Object* JSRegExp::DataAtUnchecked(int index) {
+ FixedArray* fa = reinterpret_cast<FixedArray*>(data());
+ int offset = FixedArray::kHeaderSize + index * kPointerSize;
+ return READ_FIELD(fa, offset);
+}
+
+
void JSRegExp::SetDataAt(int index, Object* value) {
ASSERT(TypeTag() != NOT_COMPILED);
ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
@@ -5368,6 +5421,18 @@
}
+void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
+ ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
+ FixedArray* fa = reinterpret_cast<FixedArray*>(data());
+ if (value->IsSmi()) {
+ fa->set_unchecked(index, Smi::cast(value));
+ } else {
+ // We only do this during GC, so we don't need to notify the write barrier.
+ fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
+ }
+}
+
+
ElementsKind JSObject::GetElementsKind() {
ElementsKind kind = map()->elements_kind();
#if DEBUG
diff --git a/src/objects.cc b/src/objects.cc
index 5459679..54d25a7 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1384,7 +1384,7 @@
global_object ? "Global Object: " : "",
vowel ? "n" : "");
accumulator->Put(str);
- accumulator->Add(" with %smap %p",
+ accumulator->Add(" with %smap 0x%p",
map_of_this->is_deprecated() ? "deprecated " : "",
map_of_this);
printed = true;
@@ -10556,8 +10556,11 @@
}
case Translation::ARGUMENTS_OBJECT: {
+ bool args_known = iterator.Next();
+ int args_index = iterator.Next();
int args_length = iterator.Next();
- PrintF(out, "{length=%d}", args_length);
+ PrintF(out, "{index=%d, length=%d, known=%d}",
+ args_index, args_length, args_known);
break;
}
}
diff --git a/src/objects.h b/src/objects.h
index dd21db3..7771eb4 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2571,7 +2571,7 @@
inline void set(int index, Object* value);
inline bool is_the_hole(int index);
- // Setter that doesn't need write barrier.
+ // Setter that doesn't need write barrier).
inline void set(int index, Smi* value);
// Setter with explicit barrier mode.
inline void set(int index, Object* value, WriteBarrierMode mode);
@@ -2585,6 +2585,12 @@
inline void set_null(Heap* heap, int index);
inline void set_the_hole(int index);
+ // Setters with less debug checks for the GC to use.
+ inline void set_unchecked(int index, Smi* value);
+ inline void set_null_unchecked(Heap* heap, int index);
+ inline void set_unchecked(Heap* heap, int index, Object* value,
+ WriteBarrierMode mode);
+
inline Object** GetFirstElementAddress();
inline bool ContainsOnlySmisOrHoles();
@@ -4547,6 +4553,7 @@
// Unchecked accessors to be used during GC.
inline ByteArray* unchecked_relocation_info();
+ inline FixedArray* unchecked_deoptimization_data();
inline int relocation_size();
@@ -5313,6 +5320,8 @@
// [constructor]: points back to the function responsible for this map.
DECL_ACCESSORS(constructor, Object)
+ inline JSFunction* unchecked_constructor();
+
// [instance descriptors]: describes the object.
DECL_ACCESSORS(instance_descriptors, DescriptorArray)
inline void InitializeDescriptors(DescriptorArray* descriptors);
@@ -5364,7 +5373,8 @@
inline void SetNumberOfProtoTransitions(int value) {
FixedArray* cache = GetPrototypeTransitions();
ASSERT(cache->length() != 0);
- cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value));
+ cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset,
+ Smi::FromInt(value));
}
// Lookup in the map's instance descriptors and fill out the result
@@ -5930,6 +5940,8 @@
// [construct stub]: Code stub for constructing instances of this function.
DECL_ACCESSORS(construct_stub, Code)
+ inline Code* unchecked_code();
+
// Returns if this function has been compiled to native code yet.
inline bool is_compiled();
@@ -7120,6 +7132,11 @@
// Set implementation data after the object has been prepared.
inline void SetDataAt(int index, Object* value);
+ // Used during GC when flushing code or setting age.
+ inline Object* DataAtUnchecked(int index);
+ inline void SetDataAtUnchecked(int index, Object* value, Heap* heap);
+ inline Type TypeTagUnchecked();
+
static int code_index(bool is_ascii) {
if (is_ascii) {
return kIrregexpASCIICodeIndex;
diff --git a/src/property.h b/src/property.h
index 5bb2c4d..f853fc8 100644
--- a/src/property.h
+++ b/src/property.h
@@ -392,11 +392,6 @@
return IsTransition() && GetTransitionDetails(map).type() == FIELD;
}
- bool IsTransitionToConstantFunction(Map* map) {
- return IsTransition() &&
- GetTransitionDetails(map).type() == CONSTANT_FUNCTION;
- }
-
Map* GetTransitionMap() {
ASSERT(IsTransition());
return Map::cast(GetValue());
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 9b7dd34..c4b79b1 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -80,17 +80,11 @@
STATIC_ASSERT(kProfilerTicksBeforeReenablingOptimization < 256);
STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);
-// Maximum size in bytes of generate code for a function to allow OSR.
-static const int kOSRCodeSizeAllowanceBase =
- 100 * FullCodeGenerator::kCodeSizeMultiplier;
-
-static const int kOSRCodeSizeAllowancePerTick =
- 3 * FullCodeGenerator::kCodeSizeMultiplier;
// Maximum size in bytes of generated code for a function to be optimized
// the very first time it is seen on the stack.
static const int kMaxSizeEarlyOpt =
- 5 * FullCodeGenerator::kCodeSizeMultiplier;
+ 5 * FullCodeGenerator::kBackEdgeDistanceUnit;
RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
@@ -106,13 +100,14 @@
}
-static void GetICCounts(Code* shared_code,
+static void GetICCounts(JSFunction* function,
int* ic_with_type_info_count,
int* ic_total_count,
int* percentage) {
*ic_total_count = 0;
*ic_with_type_info_count = 0;
- Object* raw_info = shared_code->type_feedback_info();
+ Object* raw_info =
+ function->shared()->code()->type_feedback_info();
if (raw_info->IsTypeFeedbackInfo()) {
TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info);
*ic_with_type_info_count = info->ic_with_type_info_count();
@@ -133,7 +128,7 @@
PrintF(" for recompilation, reason: %s", reason);
if (FLAG_type_info_threshold > 0) {
int typeinfo, total, percentage;
- GetICCounts(function->shared()->code(), &typeinfo, &total, &percentage);
+ GetICCounts(function, &typeinfo, &total, &percentage);
PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, percentage);
}
PrintF("]\n");
@@ -279,20 +274,12 @@
(function->IsMarkedForLazyRecompilation() ||
function->IsMarkedForParallelRecompilation() ||
function->IsOptimized())) {
- int ticks = shared_code->profiler_ticks();
- int allowance = kOSRCodeSizeAllowanceBase +
- ticks * kOSRCodeSizeAllowancePerTick;
- if (shared_code->CodeSize() > allowance) {
- if (ticks < 255) shared_code->set_profiler_ticks(ticks + 1);
- } else {
- int nesting = shared_code->allow_osr_at_loop_nesting_level();
- if (nesting < Code::kMaxLoopNestingMarker) {
- int new_nesting = nesting + 1;
- shared_code->set_allow_osr_at_loop_nesting_level(new_nesting);
- AttemptOnStackReplacement(function);
- }
+ int nesting = shared_code->allow_osr_at_loop_nesting_level();
+ if (nesting < Code::kMaxLoopNestingMarker) {
+ int new_nesting = nesting + 1;
+ shared_code->set_allow_osr_at_loop_nesting_level(new_nesting);
+ AttemptOnStackReplacement(function);
}
- continue;
}
// Only record top-level code on top of the execution stack and
@@ -326,7 +313,7 @@
if (ticks >= kProfilerTicksBeforeOptimization) {
int typeinfo, total, percentage;
- GetICCounts(shared_code, &typeinfo, &total, &percentage);
+ GetICCounts(function, &typeinfo, &total, &percentage);
if (percentage >= FLAG_type_info_threshold) {
// If this particular function hasn't had any ICs patched for enough
// ticks, optimize it now.
diff --git a/src/runtime-profiler.h b/src/runtime-profiler.h
index 46da381..1bf9aa8 100644
--- a/src/runtime-profiler.h
+++ b/src/runtime-profiler.h
@@ -75,8 +75,6 @@
void AddSample(JSFunction* function, int weight);
- bool CodeSizeOKForOSR(Code* shared_code);
-
Isolate* isolate_;
int sampler_threshold_;
diff --git a/src/sampler.cc b/src/sampler.cc
index 96b20f0..efac288 100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -496,7 +496,9 @@
void SampleContext(Sampler* sampler) {
if (!SignalHandler::Installed()) return;
pthread_t tid = sampler->platform_data()->vm_tid();
- pthread_kill(tid, SIGPROF);
+ int result = pthread_kill(tid, SIGPROF);
+ USE(result);
+ ASSERT(result == 0);
}
#elif defined(__MACH__)
diff --git a/src/spaces.cc b/src/spaces.cc
index 60293ea..8e953e2 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1045,7 +1045,7 @@
size = 16 * kPointerSize * KB;
break;
case PROPERTY_CELL_SPACE:
- size = 8 * kPointerSize * KB;
+ size = 16 * kPointerSize * KB;
break;
case CODE_SPACE:
if (heap()->isolate()->code_range()->exists()) {
@@ -2118,13 +2118,13 @@
while (node != NULL &&
Page::FromAddress(node->address())->IsEvacuationCandidate()) {
- available_ -= reinterpret_cast<FreeSpace*>(node)->Size();
+ available_ -= node->Size();
node = node->next();
}
if (node != NULL) {
set_top(node->next());
- *node_size = reinterpret_cast<FreeSpace*>(node)->Size();
+ *node_size = node->Size();
available_ -= *node_size;
} else {
set_top(NULL);
@@ -2138,18 +2138,6 @@
}
-FreeListNode* FreeListCategory::PickNodeFromList(int size_in_bytes,
- int *node_size) {
- FreeListNode* node = PickNodeFromList(node_size);
- if (node != NULL && *node_size < size_in_bytes) {
- Free(node, *node_size);
- *node_size = 0;
- return NULL;
- }
- return node;
-}
-
-
void FreeListCategory::Free(FreeListNode* node, int size_in_bytes) {
node->set_next(top_);
top_ = node;
@@ -2239,10 +2227,8 @@
if (size_in_bytes <= kSmallAllocationMax) {
node = small_list_.PickNodeFromList(node_size);
if (node != NULL) {
- ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address());
page->add_available_in_small_free_list(-(*node_size));
- ASSERT(IsVeryLong() || available() == SumFreeLists());
return node;
}
}
@@ -2250,10 +2236,8 @@
if (size_in_bytes <= kMediumAllocationMax) {
node = medium_list_.PickNodeFromList(node_size);
if (node != NULL) {
- ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address());
page->add_available_in_medium_free_list(-(*node_size));
- ASSERT(IsVeryLong() || available() == SumFreeLists());
return node;
}
}
@@ -2261,10 +2245,8 @@
if (size_in_bytes <= kLargeAllocationMax) {
node = large_list_.PickNodeFromList(node_size);
if (node != NULL) {
- ASSERT(size_in_bytes <= *node_size);
page = Page::FromAddress(node->address());
page->add_available_in_large_free_list(-(*node_size));
- ASSERT(IsVeryLong() || available() == SumFreeLists());
return node;
}
}
@@ -2307,37 +2289,10 @@
if (huge_list_.top() == NULL) {
huge_list_.set_end(NULL);
}
+
huge_list_.set_available(huge_list_available);
-
- if (node != NULL) {
- ASSERT(IsVeryLong() || available() == SumFreeLists());
- return node;
- }
-
- if (size_in_bytes <= kSmallListMax) {
- node = small_list_.PickNodeFromList(size_in_bytes, node_size);
- if (node != NULL) {
- ASSERT(size_in_bytes <= *node_size);
- page = Page::FromAddress(node->address());
- page->add_available_in_small_free_list(-(*node_size));
- }
- } else if (size_in_bytes <= kMediumListMax) {
- node = medium_list_.PickNodeFromList(size_in_bytes, node_size);
- if (node != NULL) {
- ASSERT(size_in_bytes <= *node_size);
- page = Page::FromAddress(node->address());
- page->add_available_in_medium_free_list(-(*node_size));
- }
- } else if (size_in_bytes <= kLargeListMax) {
- node = large_list_.PickNodeFromList(size_in_bytes, node_size);
- if (node != NULL) {
- ASSERT(size_in_bytes <= *node_size);
- page = Page::FromAddress(node->address());
- page->add_available_in_large_free_list(-(*node_size));
- }
- }
-
ASSERT(IsVeryLong() || available() == SumFreeLists());
+
return node;
}
diff --git a/src/spaces.h b/src/spaces.h
index d964549..ca61081 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1454,7 +1454,6 @@
void Free(FreeListNode* node, int size_in_bytes);
FreeListNode* PickNodeFromList(int *node_size);
- FreeListNode* PickNodeFromList(int size_in_bytes, int *node_size);
intptr_t EvictFreeListItemsInList(Page* p);
diff --git a/src/version.cc b/src/version.cc
index 8ce773f..e731392 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
#define MINOR_VERSION 19
-#define BUILD_NUMBER 16
-#define PATCH_LEVEL 1
+#define BUILD_NUMBER 17
+#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 8868c7a..40025d3 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -6636,11 +6636,11 @@
void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : element value to store
+ // -- rbx : array literal
+ // -- rdi : map of array literal
// -- rcx : element index as smi
+ // -- rdx : array literal index in function
// -- rsp[0] : return address
- // -- rsp[8] : array literal index in function
- // -- rsp[16]: array literal
- // clobbers rbx, rdx, rdi
// -----------------------------------
Label element_done;
@@ -6649,11 +6649,6 @@
Label slow_elements;
Label fast_elements;
- // Get array literal index, array literal and its map.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
- __ movq(rbx, Operand(rsp, 2 * kPointerSize));
- __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
-
__ CheckFastElements(rdi, &double_elements);
// FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index e5d190a..4afcadb 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -337,7 +337,7 @@
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
@@ -378,7 +378,7 @@
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
+ Max(1, distance / kBackEdgeDistanceUnit));
}
EmitProfilingCounterDecrement(weight);
Label ok;
@@ -1812,8 +1812,7 @@
}
if (!result_saved) {
- __ push(rax); // array literal
- __ Push(Smi::FromInt(expr->literal_index()));
+ __ push(rax);
result_saved = true;
}
VisitForAccumulatorValue(subexpr);
@@ -1822,7 +1821,7 @@
// Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they
// cannot transition and don't need to call the runtime stub.
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
- __ movq(rbx, Operand(rsp, kPointerSize)); // Copy of array literal.
+ __ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
__ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
// Store the subexpression value in the array's elements.
__ movq(FieldOperand(rbx, offset), result_register());
@@ -1833,7 +1832,10 @@
INLINE_SMI_CHECK);
} else {
// Store the subexpression value in the array's elements.
+ __ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
+ __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
__ Move(rcx, Smi::FromInt(i));
+ __ Move(rdx, Smi::FromInt(expr->literal_index()));
StoreArrayLiteralElementStub stub;
__ CallStub(&stub);
}
@@ -1842,7 +1844,6 @@
}
if (result_saved) {
- __ addq(rsp, Immediate(kPointerSize)); // literal index
context()->PlugTOS();
} else {
context()->Plug(rax);
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index ce91eff..efb41c8 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -1502,8 +1502,8 @@
}
-void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
- StrictModeFlag strict_mode) {
+void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
+ StrictModeFlag strict_mode) {
// ----------- S t a t e -------------
// -- rax : value
// -- rcx : name
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 1dd27ac..18958db 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -469,15 +469,27 @@
void LCodeGen::WriteTranslation(LEnvironment* environment,
- Translation* translation) {
+ Translation* translation,
+ int* pushed_arguments_index,
+ int* pushed_arguments_count) {
if (environment == NULL) return;
// The translation includes one command per value in the environment.
- int translation_size = environment->translation_size();
+ int translation_size = environment->values()->length();
// The output frame height does not include the parameters.
int height = translation_size - environment->parameter_count();
- WriteTranslation(environment->outer(), translation);
+ // Function parameters are arguments to the outermost environment. The
+ // arguments index points to the first element of a sequence of tagged
+ // values on the stack that represent the arguments. This needs to be
+ // kept in sync with the LArgumentsElements implementation.
+ *pushed_arguments_index = -environment->parameter_count();
+ *pushed_arguments_count = environment->parameter_count();
+
+ WriteTranslation(environment->outer(),
+ translation,
+ pushed_arguments_index,
+ pushed_arguments_count);
bool has_closure_id = !info()->closure().is_null() &&
!info()->closure().is_identical_to(environment->closure());
int closure_id = has_closure_id
@@ -509,6 +521,23 @@
break;
}
+ // Inlined frames which push their arguments cause the index to be
+ // bumped and another stack area to be used for materialization,
+ // otherwise actual argument values are unknown for inlined frames.
+ bool arguments_known = true;
+ int arguments_index = *pushed_arguments_index;
+ int arguments_count = *pushed_arguments_count;
+ if (environment->entry() != NULL) {
+ arguments_known = environment->entry()->arguments_pushed();
+ arguments_index = arguments_index < 0
+ ? GetStackSlotCount() : arguments_index + arguments_count;
+ arguments_count = environment->entry()->arguments_count() + 1;
+ if (environment->entry()->arguments_pushed()) {
+ *pushed_arguments_index = arguments_index;
+ *pushed_arguments_count = arguments_count;
+ }
+ }
+
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
// spilled_registers_ and spilled_double_registers_ are either
@@ -520,7 +549,10 @@
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
@@ -529,36 +561,20 @@
translation,
environment->spilled_double_registers()[value->index()],
false,
- false);
+ false,
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
- // TODO(mstarzinger): Introduce marker operands to indicate that this value
- // is not present and must be reconstructed from the deoptimizer. Currently
- // this is only used for the arguments object.
- if (value == NULL) {
- int arguments_count = environment->values()->length() - translation_size;
- translation->BeginArgumentsObject(arguments_count);
- for (int i = 0; i < arguments_count; ++i) {
- LOperand* value = environment->values()->at(translation_size + i);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsRegister() ||
- environment->spilled_registers()[value->index()] == NULL);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsDoubleRegister() ||
- environment->spilled_double_registers()[value->index()] == NULL);
- AddToTranslation(translation,
- value,
- environment->HasTaggedValueAt(translation_size + i),
- environment->HasUint32ValueAt(translation_size + i));
- }
- continue;
- }
-
AddToTranslation(translation,
value,
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ arguments_known,
+ arguments_index,
+ arguments_count);
}
}
@@ -566,8 +582,17 @@
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32) {
- if (op->IsStackSlot()) {
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count) {
+ if (op == NULL) {
+ // TODO(twuerthinger): Introduce marker operands to indicate that this value
+ // is not present and must be reconstructed from the deoptimizer. Currently
+ // this is only used for the arguments object.
+ translation->StoreArgumentsObject(
+ arguments_known, arguments_index, arguments_count);
+ } else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
} else if (is_uint32) {
@@ -672,6 +697,8 @@
int frame_count = 0;
int jsframe_count = 0;
+ int args_index = 0;
+ int args_count = 0;
for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
++frame_count;
if (e->frame_type() == JS_FUNCTION) {
@@ -679,7 +706,7 @@
}
}
Translation translation(&translations_, frame_count, jsframe_count, zone());
- WriteTranslation(environment, &translation);
+ WriteTranslation(environment, &translation, &args_index, &args_count);
int deoptimization_index = deoptimizations_.length();
int pc_offset = masm()->pc_offset();
environment->Register(deoptimization_index,
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 31dd9c4..c3f99c4 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -139,7 +139,10 @@
void DoGap(LGap* instr);
// Emit frame translation commands for an environment.
- void WriteTranslation(LEnvironment* environment, Translation* translation);
+ void WriteTranslation(LEnvironment* environment,
+ Translation* translation,
+ int* arguments_index,
+ int* arguments_count);
// Declare methods that deal with the individual node types.
#define DECLARE_DO(type) void Do##type(L##type* node);
@@ -250,7 +253,10 @@
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32);
+ bool is_uint32,
+ bool arguments_known,
+ int arguments_index,
+ int arguments_count);
void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 5d37221..cb0659d 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -937,7 +937,7 @@
BailoutId ast_id = hydrogen_env->ast_id();
ASSERT(!ast_id.IsNone() ||
hydrogen_env->frame_type() != JS_FUNCTION);
- int value_count = hydrogen_env->length() - hydrogen_env->specials_count();
+ int value_count = hydrogen_env->length();
LEnvironment* result = new(zone()) LEnvironment(
hydrogen_env->closure(),
hydrogen_env->frame_type(),
@@ -948,15 +948,13 @@
outer,
hydrogen_env->entry(),
zone());
- bool needs_arguments_object_materialization = false;
int argument_index = *argument_index_accumulator;
- for (int i = 0; i < hydrogen_env->length(); ++i) {
+ for (int i = 0; i < value_count; ++i) {
if (hydrogen_env->is_special_index(i)) continue;
HValue* value = hydrogen_env->values()->at(i);
LOperand* op = NULL;
if (value->IsArgumentsObject()) {
- needs_arguments_object_materialization = true;
op = NULL;
} else if (value->IsPushArgument()) {
op = new(zone()) LArgument(argument_index++);
@@ -968,21 +966,6 @@
value->CheckFlag(HInstruction::kUint32));
}
- if (needs_arguments_object_materialization) {
- HArgumentsObject* arguments = hydrogen_env->entry() == NULL
- ? graph()->GetArgumentsObject()
- : hydrogen_env->entry()->arguments_object();
- ASSERT(arguments->IsLinked());
- for (int i = 1; i < arguments->arguments_count(); ++i) {
- HValue* value = arguments->arguments_values()->at(i);
- ASSERT(!value->IsArgumentsObject() && !value->IsPushArgument());
- LOperand* op = UseAny(value);
- result->AddValue(op,
- value->representation(),
- value->CheckFlag(HInstruction::kUint32));
- }
- }
-
if (hydrogen_env->frame_type() == JS_FUNCTION) {
*argument_index_accumulator = argument_index;
}
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b6a1d34..a2568a4 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -697,8 +697,6 @@
void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
- Address thunk_address,
- Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset) {
@@ -739,29 +737,9 @@
PopSafepointRegisters();
}
-
- Label profiler_disabled;
- Label end_profiler_check;
- bool* is_profiling_flag =
- isolate()->cpu_profiler()->is_profiling_address();
- STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
- movq(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE);
- cmpb(Operand(rax, 0), Immediate(0));
- j(zero, &profiler_disabled);
-
- // Third parameter is the address of the actual getter function.
- movq(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE);
- movq(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE);
- jmp(&end_profiler_check);
-
- bind(&profiler_disabled);
// Call the api function!
movq(rax, reinterpret_cast<int64_t>(function_address),
RelocInfo::EXTERNAL_REFERENCE);
-
- bind(&end_profiler_check);
-
- // Call the api function!
call(rax);
if (FLAG_log_timer_events) {
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 1b7e586..7b8747c 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -1239,8 +1239,6 @@
// caller-save registers. Restores context. On return removes
// stack_space * kPointerSize (GCed).
void CallApiFunctionAndReturn(Address function_address,
- Address thunk_address,
- Register thunk_last_arg,
int stack_space,
bool returns_handle,
int return_value_offset_from_rbp);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 733da3b..c105905 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -491,14 +491,11 @@
#if defined(__MINGW64__)
Register arguments_arg = rcx;
- Register callback_arg = rdx;
#elif defined(_WIN64)
// Win64 uses first register--rcx--for returned value.
Register arguments_arg = returns_handle ? rdx : rcx;
- Register callback_arg = returns_handle ? r8 : rdx;
#else
Register arguments_arg = rdi;
- Register callback_arg = rsi;
#endif
// Allocate the v8::Arguments structure in the arguments' space since
@@ -517,13 +514,7 @@
// v8::InvocationCallback's argument.
__ lea(arguments_arg, StackSpaceOperand(0));
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
-
__ CallApiFunctionAndReturn(function_address,
- thunk_address,
- callback_arg,
argc + kFastApiCallArguments + 1,
returns_handle,
kFastApiCallArguments + 1);
@@ -826,13 +817,7 @@
Register storage_reg = name_reg;
- if (details.type() == CONSTANT_FUNCTION) {
- Handle<HeapObject> constant(
- HeapObject::cast(descriptors->GetValue(descriptor)));
- __ LoadHeapObject(scratch1, constant);
- __ cmpq(value_reg, scratch1);
- __ j(not_equal, miss_restore_name);
- } else if (FLAG_track_fields && representation.IsSmi()) {
+ if (FLAG_track_fields && representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_restore_name);
} else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
__ JumpIfSmi(value_reg, miss_restore_name);
@@ -859,8 +844,7 @@
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
// Perform map transition for the receiver if necessary.
- if (details.type() == FIELD &&
- object->map()->unused_property_fields() == 0) {
+ 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 properties array.
__ pop(scratch1); // Return address.
@@ -889,8 +873,6 @@
OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
- if (details.type() == CONSTANT_FUNCTION) return;
-
int index = transition->instance_descriptors()->GetFieldIndex(
transition->LastAdded());
@@ -1336,16 +1318,13 @@
!CallbackTable::ReturnsVoid(isolate(), getter_address);
#if defined(__MINGW64__)
- Register getter_arg = r8;
Register accessor_info_arg = rdx;
Register name_arg = rcx;
#elif defined(_WIN64)
// Win64 uses first register--rcx--for returned value.
- Register getter_arg = returns_handle ? r9 : r8;
Register accessor_info_arg = returns_handle ? r8 : rdx;
Register name_arg = returns_handle ? rdx : rcx;
#else
- Register getter_arg = rdx;
Register accessor_info_arg = rsi;
Register name_arg = rdi;
#endif
@@ -1371,13 +1350,7 @@
// could be used to pass arguments.
__ lea(accessor_info_arg, StackSpaceOperand(0));
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
-
__ CallApiFunctionAndReturn(getter_address,
- thunk_address,
- getter_arg,
kStackSpace,
returns_handle,
5);