Commit fa69fd08 authored by danno@chromium.org's avatar danno@chromium.org

Fix opmitized external array access for compound assignments and count...

Fix opmitized external array access for compound assignments and count operations, also implement missing ARM typed array Hydrogen loads and stores.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/6805005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7536 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent eb1443eb
......@@ -1840,21 +1840,20 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) {
// TODO(danno): Add support for other external array types.
if (instr->array_type() != kExternalPixelArray) {
Abort("unsupported load for external array type.");
return NULL;
}
ASSERT(instr->representation().IsInteger32());
ExternalArrayType array_type = instr->array_type();
Representation representation(instr->representation());
ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
(representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer =
UseRegisterAtStart(instr->external_pointer());
LOperand* key = UseRegisterAtStart(instr->key());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegister(instr->key());
LLoadKeyedSpecializedArrayElement* result =
new LLoadKeyedSpecializedArrayElement(external_pointer,
key);
return DefineAsRegister(result);
new LLoadKeyedSpecializedArrayElement(external_pointer, key);
LInstruction* load_instr = DefineAsRegister(result);
// An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment.
return (array_type == kExternalUnsignedIntArray) ?
AssignEnvironment(load_instr) : load_instr;
}
......@@ -1889,23 +1888,24 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) {
// TODO(danno): Add support for other external array types.
if (instr->array_type() != kExternalPixelArray) {
Abort("unsupported store for external array type.");
return NULL;
}
ASSERT(instr->value()->representation().IsInteger32());
Representation representation(instr->value()->representation());
ExternalArrayType array_type = instr->array_type();
ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
(representation.IsDouble() && array_type == kExternalFloatArray));
ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* value = UseTempRegister(instr->value()); // changed by clamp.
bool val_is_temp_register = array_type == kExternalPixelArray ||
array_type == kExternalFloatArray;
LOperand* val = val_is_temp_register
? UseTempRegister(instr->value())
: UseRegister(instr->value());
LOperand* key = UseRegister(instr->key());
return new LStoreKeyedSpecializedArrayElement(external_pointer,
key,
value);
val);
}
......
......@@ -2383,12 +2383,13 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
__ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
__ cmp(scratch, ip);
__ b(eq, &done);
__ LoadRoot(ip, Heap::kExternalPixelArrayMapRootIndex);
__ cmp(scratch, ip);
__ b(eq, &done);
__ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
__ cmp(scratch, ip);
__ Check(eq, "Check for fast elements failed.");
__ ldr(scratch, FieldMemOperand(result, HeapObject::kMapOffset));
__ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
__ sub(scratch, scratch, Operand(FIRST_EXTERNAL_ARRAY_TYPE));
__ cmp(scratch, Operand(kExternalArrayTypeCount));
__ Check(cc, "Check for fast elements failed.");
__ bind(&done);
}
}
......@@ -2441,14 +2442,51 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
ASSERT(instr->array_type() == kExternalPixelArray);
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
Register result = ToRegister(instr->result());
// Load the result.
__ ldrb(result, MemOperand(external_pointer, key));
ExternalArrayType array_type = instr->array_type();
if (array_type == kExternalFloatArray) {
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
DwVfpRegister result(ToDoubleRegister(instr->result()));
__ add(scratch0(), external_pointer, Operand(key, LSL, 2));
__ vldr(result, scratch0(), 0);
} else {
Register result(ToRegister(instr->result()));
__ ldr(result, MemOperand(external_pointer, key, LSL, 2));
}
} else {
Register result(ToRegister(instr->result()));
switch (array_type) {
case kExternalByteArray:
__ ldrsb(result, MemOperand(external_pointer, key));
break;
case kExternalUnsignedByteArray:
case kExternalPixelArray:
__ ldrb(result, MemOperand(external_pointer, key));
break;
case kExternalShortArray:
__ ldrsh(result, MemOperand(external_pointer, key, LSL, 1));
break;
case kExternalUnsignedShortArray:
__ ldrh(result, MemOperand(external_pointer, key, LSL, 1));
break;
case kExternalIntArray:
__ ldr(result, MemOperand(external_pointer, key, LSL, 2));
break;
case kExternalUnsignedIntArray:
__ ldr(result, MemOperand(external_pointer, key, LSL, 2));
__ cmp(result, Operand(0x80000000));
// TODO(danno): we could be more clever here, perhaps having a special
// version of the stub that detects if the overflow case actually
// happens, and generate code that returns a double rather than int.
DeoptimizeIf(cs, instr->environment());
break;
case kExternalFloatArray:
UNREACHABLE();
break;
}
}
}
......@@ -3112,15 +3150,45 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LStoreKeyedSpecializedArrayElement* instr) {
ASSERT(instr->array_type() == kExternalPixelArray);
Register external_pointer = ToRegister(instr->external_pointer());
Register key = ToRegister(instr->key());
Register value = ToRegister(instr->value());
// Clamp the value to [0..255].
__ Usat(value, 8, Operand(value));
__ strb(value, MemOperand(external_pointer, key, LSL, 0));
ExternalArrayType array_type = instr->array_type();
if (array_type == kExternalFloatArray) {
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
DwVfpRegister value(ToDoubleRegister(instr->value()));
__ add(scratch0(), external_pointer, Operand(key, LSL, 2));
__ vstr(value, scratch0(), 0);
} else {
Register value(ToRegister(instr->value()));
__ str(value, MemOperand(external_pointer, key, LSL, 2));
}
} else {
Register value(ToRegister(instr->value()));
switch (array_type) {
case kExternalPixelArray:
// Clamp the value to [0..255].
__ Usat(value, 8, Operand(value));
__ strb(value, MemOperand(external_pointer, key));
break;
case kExternalByteArray:
case kExternalUnsignedByteArray:
__ strb(value, MemOperand(external_pointer, key));
break;
case kExternalShortArray:
case kExternalUnsignedShortArray:
__ strh(value, MemOperand(external_pointer, key, LSL, 1));
break;
case kExternalIntArray:
case kExternalUnsignedIntArray:
__ str(value, MemOperand(external_pointer, key, LSL, 2));
break;
case kExternalFloatArray:
UNREACHABLE();
break;
}
}
}
......
// Copyright 2010 the V8 project authors. All rights reserved.
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -549,7 +549,7 @@ void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
} else if (is_monomorphic_) {
monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
if (monomorphic_receiver_type_->has_external_array_elements()) {
SetExternalArrayType(oracle->GetKeyedLoadExternalArrayType(this));
set_external_array_type(oracle->GetKeyedLoadExternalArrayType(this));
}
}
}
......@@ -569,7 +569,19 @@ void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
// Record receiver type for monomorphic keyed loads.
monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
if (monomorphic_receiver_type_->has_external_array_elements()) {
SetExternalArrayType(oracle->GetKeyedStoreExternalArrayType(this));
set_external_array_type(oracle->GetKeyedStoreExternalArrayType(this));
}
}
}
void CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
is_monomorphic_ = oracle->StoreIsMonomorphic(this);
if (is_monomorphic_) {
// Record receiver type for monomorphic keyed loads.
monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
if (monomorphic_receiver_type_->has_external_array_elements()) {
set_external_array_type(oracle->GetKeyedStoreExternalArrayType(this));
}
}
}
......
......@@ -221,6 +221,11 @@ class Expression: public AstNode {
Expression() : bitfields_(0) {}
virtual int position() const {
UNREACHABLE();
return 0;
}
virtual Expression* AsExpression() { return this; }
virtual bool IsTrivial() { return false; }
......@@ -317,6 +322,14 @@ class Expression: public AstNode {
bitfields_ |= NumBitOpsField::encode(num_bit_ops);
}
ExternalArrayType external_array_type() const {
return ExternalArrayTypeField::decode(bitfields_);
}
void set_external_array_type(ExternalArrayType array_type) {
bitfields_ &= ~ExternalArrayTypeField::mask();
bitfields_ |= ExternalArrayTypeField::encode(array_type);
}
private:
static const int kMaxNumBitOps = (1 << 5) - 1;
......@@ -329,6 +342,7 @@ class Expression: public AstNode {
class ToInt32Field : public BitField<bool, 2, 1> {};
class NumBitOpsField : public BitField<int, 3, 5> {};
class LoopConditionField: public BitField<bool, 8, 1> {};
class ExternalArrayTypeField: public BitField<ExternalArrayType, 9, 4> {};
};
......@@ -695,7 +709,7 @@ class CaseClause: public ZoneObject {
JumpTarget* body_target() { return &body_target_; }
ZoneList<Statement*>* statements() const { return statements_; }
int position() { return position_; }
int position() const { return position_; }
void set_position(int pos) { position_ = pos; }
int EntryId() { return entry_id_; }
......@@ -1245,7 +1259,7 @@ class Property: public Expression {
Expression* obj() const { return obj_; }
Expression* key() const { return key_; }
int position() const { return pos_; }
virtual int position() const { return pos_; }
bool is_synthetic() const { return type_ == SYNTHETIC; }
bool IsStringLength() const { return is_string_length_; }
......@@ -1259,11 +1273,6 @@ class Property: public Expression {
}
bool is_arguments_access() const { return is_arguments_access_; }
ExternalArrayType GetExternalArrayType() const { return array_type_; }
void SetExternalArrayType(ExternalArrayType array_type) {
array_type_ = array_type;
}
// Type feedback information.
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual bool IsMonomorphic() { return is_monomorphic_; }
......@@ -1287,7 +1296,6 @@ class Property: public Expression {
bool is_function_prototype_ : 1;
bool is_arguments_access_ : 1;
Handle<Map> monomorphic_receiver_type_;
ExternalArrayType array_type_;
};
......@@ -1309,7 +1317,7 @@ class Call: public Expression {
Expression* expression() const { return expression_; }
ZoneList<Expression*>* arguments() const { return arguments_; }
int position() { return pos_; }
virtual int position() const { return pos_; }
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
......@@ -1387,7 +1395,7 @@ class CallNew: public Expression {
Expression* expression() const { return expression_; }
ZoneList<Expression*>* arguments() const { return arguments_; }
int position() { return pos_; }
virtual int position() const { return pos_; }
private:
Expression* expression_;
......@@ -1470,7 +1478,7 @@ class BinaryOperation: public Expression {
Token::Value op() const { return op_; }
Expression* left() const { return left_; }
Expression* right() const { return right_; }
int position() const { return pos_; }
virtual int position() const { return pos_; }
// Bailout support.
int RightId() const { return right_id_; }
......@@ -1507,12 +1515,18 @@ class CountOperation: public Expression {
}
Expression* expression() const { return expression_; }
int position() const { return pos_; }
virtual int position() const { return pos_; }
virtual void MarkAsStatement() { is_prefix_ = true; }
virtual bool IsInlineable() const;
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual bool IsMonomorphic() { return is_monomorphic_; }
virtual Handle<Map> GetMonomorphicReceiverType() {
return monomorphic_receiver_type_;
}
// Bailout support.
int AssignmentId() const { return assignment_id_; }
int CountId() const { return count_id_; }
......@@ -1520,10 +1534,12 @@ class CountOperation: public Expression {
private:
Token::Value op_;
bool is_prefix_;
bool is_monomorphic_;
Expression* expression_;
int pos_;
int assignment_id_;
int count_id_;
Handle<Map> monomorphic_receiver_type_;
};
......@@ -1542,7 +1558,7 @@ class CompareOperation: public Expression {
Token::Value op() const { return op_; }
Expression* left() const { return left_; }
Expression* right() const { return right_; }
int position() const { return pos_; }
virtual int position() const { return pos_; }
virtual bool IsInlineable() const;
......@@ -1637,7 +1653,7 @@ class Assignment: public Expression {
Token::Value op() const { return op_; }
Expression* target() const { return target_; }
Expression* value() const { return value_; }
int position() { return pos_; }
virtual int position() const { return pos_; }
BinaryOperation* binary_operation() const { return binary_operation_; }
// This check relies on the definition order of token in token.h.
......@@ -1659,10 +1675,6 @@ class Assignment: public Expression {
virtual Handle<Map> GetMonomorphicReceiverType() {
return monomorphic_receiver_type_;
}
ExternalArrayType GetExternalArrayType() const { return array_type_; }
void SetExternalArrayType(ExternalArrayType array_type) {
array_type_ = array_type;
}
// Bailout support.
int CompoundLoadId() const { return compound_load_id_; }
......@@ -1683,7 +1695,6 @@ class Assignment: public Expression {
bool is_monomorphic_;
ZoneMapList* receiver_types_;
Handle<Map> monomorphic_receiver_type_;
ExternalArrayType array_type_;
};
......@@ -1695,7 +1706,7 @@ class Throw: public Expression {
DECLARE_NODE_TYPE(Throw)
Expression* exception() const { return exception_; }
int position() const { return pos_; }
virtual int position() const { return pos_; }
private:
Expression* exception_;
......
......@@ -3264,26 +3264,8 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
value = Pop();
HValue* key = Pop();
HValue* object = Pop();
if (expr->IsMonomorphic()) {
Handle<Map> receiver_type(expr->GetMonomorphicReceiverType());
// An object has either fast elements or external array elements, but
// never both. Pixel array maps that are assigned to pixel array elements
// are always created with the fast elements flag cleared.
if (receiver_type->has_external_array_elements()) {
instr = BuildStoreKeyedSpecializedArrayElement(object,
key,
value,
expr);
} else if (receiver_type->has_fast_elements()) {
instr = BuildStoreKeyedFastElement(object, key, value, expr);
}
}
if (instr == NULL) {
instr = BuildStoreKeyedGeneric(object, key, value);
}
instr = BuildStoreKeyed(object, key, value, expr);
}
Push(value);
instr->set_position(expr->position());
AddInstruction(instr);
......@@ -3402,11 +3384,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HValue* obj = environment()->ExpressionStackAt(1);
HValue* key = environment()->ExpressionStackAt(0);
bool is_fast_elements = prop->IsMonomorphic() &&
prop->GetMonomorphicReceiverType()->has_fast_elements();
HInstruction* load = is_fast_elements
? BuildLoadKeyedFastElement(obj, key, prop)
: BuildLoadKeyedGeneric(obj, key);
HInstruction* load = BuildLoadKeyed(obj, key, prop);
PushAndAdd(load);
if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId());
......@@ -3418,9 +3396,8 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
PushAndAdd(instr);
if (instr->HasSideEffects()) AddSimulate(operation->id());
HInstruction* store = is_fast_elements
? BuildStoreKeyedFastElement(obj, key, instr, prop)
: BuildStoreKeyedGeneric(obj, key, instr);
expr->RecordTypeFeedback(oracle());
HInstruction* store = BuildStoreKeyed(obj, key, instr, expr);
AddInstruction(store);
// Drop the simulated receiver, key, and value. Return the value.
Drop(3);
......@@ -3623,11 +3600,29 @@ HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement(
AddInstruction(external_elements);
HLoadKeyedSpecializedArrayElement* pixel_array_value =
new(zone()) HLoadKeyedSpecializedArrayElement(
external_elements, key, expr->GetExternalArrayType());
external_elements, key, expr->external_array_type());
return pixel_array_value;
}
HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj,
HValue* key,
Property* prop) {
if (prop->IsMonomorphic()) {
Handle<Map> receiver_type(prop->GetMonomorphicReceiverType());
// An object has either fast elements or pixel array elements, but never
// both. Pixel array maps that are assigned to pixel array elements are
// always created with the fast elements flag cleared.
if (receiver_type->has_external_array_elements()) {
return BuildLoadKeyedSpecializedArrayElement(obj, key, prop);
} else if (receiver_type->has_fast_elements()) {
return BuildLoadKeyedFastElement(obj, key, prop);
}
}
return BuildLoadKeyedGeneric(obj, key);
}
HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object,
HValue* key,
HValue* value) {
......@@ -3665,7 +3660,7 @@ HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
HValue* object,
HValue* key,
HValue* val,
Assignment* expr) {
Expression* expr) {
ASSERT(expr->IsMonomorphic());
AddInstruction(new(zone()) HCheckNonSmi(object));
Handle<Map> map = expr->GetMonomorphicReceiverType();
......@@ -3684,7 +3679,29 @@ HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
external_elements,
key,
val,
expr->GetExternalArrayType());
expr->external_array_type());
}
HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object,
HValue* key,
HValue* value,
Expression* expr) {
if (expr->IsMonomorphic()) {
Handle<Map> receiver_type(expr->GetMonomorphicReceiverType());
// An object has either fast elements or external array elements, but
// never both. Pixel array maps that are assigned to pixel array elements
// are always created with the fast elements flag cleared.
if (receiver_type->has_external_array_elements()) {
return BuildStoreKeyedSpecializedArrayElement(object,
key,
value,
expr);
} else if (receiver_type->has_fast_elements()) {
return BuildStoreKeyedFastElement(object, key, value, expr);
}
}
return BuildStoreKeyedGeneric(object, key, value);
}
......@@ -3775,21 +3792,7 @@ void HGraphBuilder::VisitProperty(Property* expr) {
HValue* key = Pop();
HValue* obj = Pop();
if (expr->IsMonomorphic()) {
Handle<Map> receiver_type(expr->GetMonomorphicReceiverType());
// An object has either fast elements or pixel array elements, but never
// both. Pixel array maps that are assigned to pixel array elements are
// always created with the fast elements flag cleared.
if (receiver_type->has_external_array_elements()) {
instr = BuildLoadKeyedSpecializedArrayElement(obj, key, expr);
} else if (receiver_type->has_fast_elements()) {
instr = BuildLoadKeyedFastElement(obj, key, expr);
}
}
if (instr == NULL) {
instr = BuildLoadKeyedGeneric(obj, key);
}
instr = BuildLoadKeyed(obj, key, expr);
}
instr->set_position(expr->position());
ast_context()->ReturnInstruction(instr, expr->id());
......@@ -4718,12 +4721,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
HValue* obj = environment()->ExpressionStackAt(1);
HValue* key = environment()->ExpressionStackAt(0);
bool is_fast_elements = prop->IsMonomorphic() &&
prop->GetMonomorphicReceiverType()->has_fast_elements();
HInstruction* load = is_fast_elements
? BuildLoadKeyedFastElement(obj, key, prop)
: BuildLoadKeyedGeneric(obj, key);
HInstruction* load = BuildLoadKeyed(obj, key, prop);
PushAndAdd(load);
if (load->HasSideEffects()) AddSimulate(expr->CountId());
......@@ -4733,9 +4731,8 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
HInstruction* after = BuildIncrement(before, inc);
AddInstruction(after);
HInstruction* store = is_fast_elements
? BuildStoreKeyedFastElement(obj, key, after, prop)
: BuildStoreKeyedGeneric(obj, key, after);
expr->RecordTypeFeedback(oracle());
HInstruction* store = BuildStoreKeyed(obj, key, after, expr);
AddInstruction(store);
// Drop the key from the bailout environment. Overwrite the receiver
......
......@@ -845,6 +845,10 @@ class HGraphBuilder: public AstVisitor {
HInstruction* BuildLoadKeyedGeneric(HValue* object,
HValue* key);
HInstruction* BuildLoadKeyed(HValue* obj,
HValue* key,
Property* prop);
HInstruction* BuildLoadNamed(HValue* object,
Property* prop,
Handle<Map> map,
......@@ -874,7 +878,12 @@ class HGraphBuilder: public AstVisitor {
HValue* object,
HValue* key,
HValue* val,
Assignment* expr);
Expression* expr);
HInstruction* BuildStoreKeyed(HValue* object,
HValue* key,
HValue* value,
Expression* assignment);
HValue* BuildContextChainWalk(Variable* var);
......
// Copyright 2010 the V8 project authors. All rights reserved.
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -89,7 +89,7 @@ bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) {
}
bool TypeFeedbackOracle::StoreIsMonomorphic(Assignment* expr) {
bool TypeFeedbackOracle::StoreIsMonomorphic(Expression* expr) {
Handle<Object> map_or_code(GetInfo(expr->position()));
if (map_or_code->IsMap()) return true;
if (map_or_code->IsCode()) {
......@@ -119,7 +119,7 @@ Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
}
Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Assignment* expr) {
Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
ASSERT(StoreIsMonomorphic(expr));
Handle<HeapObject> map_or_code(
Handle<HeapObject>::cast(GetInfo(expr->position())));
......@@ -178,7 +178,7 @@ ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType(
}
ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType(
Assignment* expr) {
Expression* expr) {
Handle<Object> stub = GetInfo(expr->position());
ASSERT(stub->IsCode());
return Code::cast(*stub)->external_array_type();
......
// Copyright 2010 the V8 project authors. All rights reserved.
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -239,18 +239,18 @@ class TypeFeedbackOracle BASE_EMBEDDED {
TypeFeedbackOracle(Handle<Code> code, Handle<Context> global_context);
bool LoadIsMonomorphic(Property* expr);
bool StoreIsMonomorphic(Assignment* expr);
bool StoreIsMonomorphic(Expression* expr);
bool CallIsMonomorphic(Call* expr);
Handle<Map> LoadMonomorphicReceiverType(Property* expr);
Handle<Map> StoreMonomorphicReceiverType(Assignment* expr);
Handle<Map> StoreMonomorphicReceiverType(Expression* expr);
ZoneMapList* LoadReceiverTypes(Property* expr, Handle<String> name);
ZoneMapList* StoreReceiverTypes(Assignment* expr, Handle<String> name);
ZoneMapList* CallReceiverTypes(Call* expr, Handle<String> name);
ExternalArrayType GetKeyedLoadExternalArrayType(Property* expr);
ExternalArrayType GetKeyedStoreExternalArrayType(Assignment* expr);
ExternalArrayType GetKeyedStoreExternalArrayType(Expression* expr);
CheckType GetCallCheckType(Call* expr);
Handle<JSObject> GetPrototypeForPrimitiveCheck(CheckType check);
......
// Copyright 2007-2009 the V8 project authors. All rights reserved.
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -11495,7 +11495,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
array->set(i, static_cast<ElementType>(i));
}
result = CompileRun("function ee_load_test_func(sum) {"
" for (var i=0;i<40;++i)"
" for (var i = 0; i < 40; ++i)"
" sum += ext_array[i];"
" return sum;"
"}"
......@@ -11508,7 +11508,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
// Test crankshaft external array stores
result = CompileRun("function ee_store_test_func(sum) {"
" for (var i=0;i<40;++i)"
" for (var i = 0; i < 40; ++i)"
" sum += ext_array[i] = i;"
" return sum;"
"}"
......@@ -11519,6 +11519,39 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
"sum;");
CHECK_EQ(7800000, result->Int32Value());
for (int i = 0; i < kElementCount; i++) {
array->set(i, static_cast<ElementType>(i));
}
// Test complex assignments
result = CompileRun("function ee_op_test_complex_func(sum) {"
" for (var i = 0; i < 40; ++i) {"
" sum += (ext_array[i] += 1);"
" sum += (ext_array[i] -= 1);"
" } "
" return sum;"
"}"
"sum=0;"
"for (var i=0;i<10000;++i) {"
" sum=ee_op_test_complex_func(sum);"
"}"
"sum;");
CHECK_EQ(16000000, result->Int32Value());
// Test count operations
result = CompileRun("function ee_op_test_count_func(sum) {"
" for (var i = 0; i < 40; ++i) {"
" sum += (++ext_array[i]);"
" sum += (--ext_array[i]);"
" } "
" return sum;"
"}"
"sum=0;"
"for (var i=0;i<10000;++i) {"
" sum=ee_op_test_count_func(sum);"
"}"
"sum;");
CHECK_EQ(16000000, result->Int32Value());
result = CompileRun("ext_array[3] = 33;"
"delete ext_array[3];"
"ext_array[3];");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment